mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-21 06:04:33 +00:00
Try remove privacy pkg (#466)
* try removing privacy pkg * rm more reference * trigger CI
This commit is contained in:
parent
e324d7d18f
commit
b86c7f646f
6 changed files with 1 additions and 2926 deletions
|
|
@ -22,8 +22,6 @@ import (
|
|||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/core/vm/privacy"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/common/math"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
|
|
@ -63,8 +61,6 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{
|
|||
common.BytesToAddress([]byte{6}): &bn256AddByzantium{},
|
||||
common.BytesToAddress([]byte{7}): &bn256ScalarMulByzantium{},
|
||||
common.BytesToAddress([]byte{8}): &bn256PairingByzantium{},
|
||||
common.BytesToAddress([]byte{30}): &ringSignatureVerifier{},
|
||||
common.BytesToAddress([]byte{40}): &bulletproofVerifier{},
|
||||
common.BytesToAddress([]byte{41}): &XDCxLastPrice{},
|
||||
common.BytesToAddress([]byte{42}): &XDCxEpochPrice{},
|
||||
}
|
||||
|
|
@ -81,8 +77,6 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{
|
|||
common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{},
|
||||
common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{},
|
||||
common.BytesToAddress([]byte{9}): &blake2F{},
|
||||
common.BytesToAddress([]byte{30}): &ringSignatureVerifier{},
|
||||
common.BytesToAddress([]byte{40}): &bulletproofVerifier{},
|
||||
common.BytesToAddress([]byte{41}): &XDCxLastPrice{},
|
||||
common.BytesToAddress([]byte{42}): &XDCxEpochPrice{},
|
||||
}
|
||||
|
|
@ -426,42 +420,6 @@ func runBn256Pairing(input []byte) ([]byte, error) {
|
|||
return false32Byte, nil
|
||||
}
|
||||
|
||||
type ringSignatureVerifier struct{}
|
||||
type bulletproofVerifier struct{}
|
||||
|
||||
func (c *bulletproofVerifier) RequiredGas(input []byte) uint64 {
|
||||
//the gas should depends on the ringsize
|
||||
return 100000
|
||||
}
|
||||
|
||||
func (c *ringSignatureVerifier) RequiredGas(input []byte) uint64 {
|
||||
//the gas should depends on the ringsize
|
||||
return 100000
|
||||
}
|
||||
|
||||
func (c *ringSignatureVerifier) Run(proof []byte) ([]byte, error) {
|
||||
der, err := privacy.Deserialize(proof)
|
||||
if err != nil {
|
||||
return []byte{}, errors.New("Fail to deserialize proof")
|
||||
}
|
||||
if !privacy.Verify(der, false) {
|
||||
return []byte{}, errors.New("Fail to verify ring signature")
|
||||
}
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
func (c *bulletproofVerifier) Run(proof []byte) ([]byte, error) {
|
||||
mrp := new(privacy.MultiRangeProof)
|
||||
if mrp.Deserialize(proof) != nil {
|
||||
return []byte{}, errors.New("failed to deserialize bulletproofs")
|
||||
}
|
||||
|
||||
if !privacy.MRPVerify(mrp) {
|
||||
return []byte{}, errors.New("failed to verify bulletproof")
|
||||
}
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
// bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve
|
||||
// conforming to Istanbul consensus rules.
|
||||
type bn256PairingIstanbul struct{}
|
||||
|
|
@ -488,6 +446,7 @@ func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) {
|
|||
return runBn256Pairing(input)
|
||||
}
|
||||
|
||||
|
||||
type blake2F struct{}
|
||||
|
||||
func (c *blake2F) RequiredGas(input []byte) uint64 {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1 +0,0 @@
|
|||
{"Ipp":{"L":[{"x":"7be22788517d8c7e149727c5397cf7b2d6713546dee4f974f3239a1f53e64f44","y":"b18c08695e40b801ace64f00bf7010245dcf972cad7ce1e97e441fa68575bb72"},{"x":"29956e85820c1ede4f6ec987b3c20cbf7c0fc0aa6a8cd823e73105fc681c1880","y":"228e434578a40d247a2b5f1c2a7a5154716fb06e98d8087b3dce9cc85429b72c"},{"x":"b39703b5680857d7629a39374451baae59459418c23f44f522838efd952e69db","y":"60033aa9807a0c081c530c30292eca71f61e17433513ead9caadce7997d97981"},{"x":"074cd428559b2bf9c0a6d54479254bdeedc26e655b7f0d822aec9a6d1f1068b3","y":"915958a8e24fefe8ec5e6338661567c8e6178d03ac35422284701bf2ab37d592"},{"x":"80d27e070c49f6d41d49254295a9e70ebaf82d8780c93f1c48f018609e3822dd","y":"5c5e365b72835ff1e24ff3a130e1cc332e36d891ba383752e469a667ecf5db01"},{"x":"6e9c63c3188c29d593417b5cb96ab0f149d905a194ace7a3e523d15f8f8922cd","y":"a91566f2cae911542a0658f63451b4a87cea5c668ab4220c974a640442021da6"}],"R":[{"x":"34f512b1fe0989ce77f8cb5b3a95dd31b55c38d4b6278e4923d6cf224d59c421","y":"8757d403eb39a181418db28f742f0ff3f59991929800c424ebce792f27353335"},{"x":"900bc03a4e26a61bb11de434ee150970a22dce77320b26fea1b172dbdfef5b10","y":"de9d1b833decc36f84ae4ce1be87414674ebef7b58009563f35a722347eb76d7"},{"x":"0ca13ff9d0a929b417a165ceb42c532dd54c34e8f1e9083208630dadafdb5ee4","y":"0bba4e3ac3b20cde8074d4683742f924bdb070a590c1d9d7c8f239748359015c"},{"x":"c29728cbb8393b65f8f224e587eccee9d332d2936b36bb460a9f9df720ef5add","y":"88295fbbe05f25534a43ac528a890b9a26ab3bf95a63e4803168d56b430190ce"},{"x":"4cd804793a0169e0bfe1206907cec530a733efb7cca86f08bff8d04bfb82394b","y":"453594ec2090934e75348db0db070c79b6302cf289d1907adbc198493fee417e"},{"x":"9d9a42ba4b30cc68841ce6528f0d4ffa7990b35fc533f7cb0e4bf0d26cc9c6b6","y":"d6dbdb179262c2bc1fc734d4e20a2c54c5e0b8b8d0c48ee630e146f4cef1f486"}],"A":"-2d23144bda297742e1eafb40911ccdbf2f5e950e8b73b4eaf8f78b857d5c7a93","B":"162325c6d1160e0c033135e32b57351c17ef79755cf4f19c6d6c0ba8117e8d09","Challenges":["139fb4a37d387933e43987862d67297c65af5302c6995bfe7181646dcfc169f1","d43aa9b8fdd97b12e3c4bfabf4c36c59dabb08ace9d5da221f676cc7244000e0","3013fdc8605a4dd479898c2b9abbab45ed9b9676267d8c86a0b7b737448c3d8e","b7a16a537783cd7a9e5bddad4536754a6b16a152fedd2df46a36f76a51cd66d9","5408a38e71aa569b6ddc2ccc84a3b2fa29253905072bf8ed5035406cda89e6fa","1ab61f234a5982567e51af82efd118ebcb44befabfaa5f07183471508e3f4208","3e666d903ccd1312a9a83506b298dfac2c2f11f796087d91104487a577802faa"]},"Comms":["71a29edddcf580c0ab4c992f34df4bcd7f23079bf29c07267e354c0e1b0c7b7d0d7d7f55259df2570dc37a2b6719eb58b2195f06163d29b7aca710cbf9b66560"],"A":"e7d28764b37d275ee1b0cc589ab2aa46cc60a406d6cb0def47dcb5fc49b3279dc65b2eb160328db9dc5953a263a5eba0855b51c66a5e23ac0a3b997d060643ed","S":"78aa79b16298d8c7cc587c8fe521d13b9c768256a8842e74e82970507efea3b9735e4324787071ded1e049c888aee40fe85cff0fff4ffdc4d2d3dc2a17ac306a","cy":"3e38e29bf805dc855b687f969a1a854a0c23fddb8ff1f480079929518e8df1f6","cz":"d794749e1c1442762943a40422a6f9bd284f938fce652c382fea05a0e33ca68f","T1":"45e56a5bc134b7b19d53670d57b45874a01442b58a853dd0960f4a7ec1a093f59be5d93e35a55f2006f03cf9c31801942d9a8739a9408c67d93c4dff6c9f7346","T2":"ad380e6564ae44cd6f91656e66c031cfe21aa47cc511ae51e4a2a8604bd181cd181be8eb1b8e0de71458eed4ce538667a392cc0e7c4e85ab7f4cff54161c8087","cx":"75327f647ab5124eefa92e51f769cdb64a24fe5f88a059b002f2d590c9236894","Th":"-ee380a27a0b95643f9a3a5a975c9b35638ba2a7105a36c7ffd90acdd16029323","Tau":"38059dcf3dfc1da9646f3dc66c8b1487c3375577e751e8341b2addd45ef06306","Mu":"e648b63a1857d1e9723b01ac3151c29fd723845f8aa2a7d6ae867feba8db53e5"}
|
||||
|
|
@ -1,527 +0,0 @@
|
|||
package privacy
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestInnerProductProveLen1(t *testing.T) {
|
||||
fmt.Println("TestInnerProductProve1")
|
||||
EC = genECPrimeGroupKey(1)
|
||||
a := make([]*big.Int, 1)
|
||||
b := make([]*big.Int, 1)
|
||||
|
||||
a[0] = big.NewInt(1)
|
||||
|
||||
b[0] = big.NewInt(1)
|
||||
|
||||
c := InnerProduct(a, b)
|
||||
|
||||
P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
|
||||
|
||||
ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
|
||||
|
||||
if InnerProductVerify(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
|
||||
fmt.Println("Inner Product Proof correct")
|
||||
} else {
|
||||
t.Error("Inner Product Proof incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInnerProductProveLen2(t *testing.T) {
|
||||
fmt.Println("TestInnerProductProve2")
|
||||
EC = genECPrimeGroupKey(2)
|
||||
a := make([]*big.Int, 2)
|
||||
b := make([]*big.Int, 2)
|
||||
|
||||
a[0] = big.NewInt(1)
|
||||
a[1] = big.NewInt(1)
|
||||
|
||||
b[0] = big.NewInt(1)
|
||||
b[1] = big.NewInt(1)
|
||||
|
||||
c := InnerProduct(a, b)
|
||||
|
||||
P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
|
||||
|
||||
fmt.Println("P after two vector commitment with gen ", P)
|
||||
|
||||
ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
|
||||
|
||||
if InnerProductVerify(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
|
||||
fmt.Println("Inner Product Proof correct")
|
||||
} else {
|
||||
t.Error("Inner Product Proof incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInnerProductProveLen4(t *testing.T) {
|
||||
fmt.Println("TestInnerProductProve4")
|
||||
EC = genECPrimeGroupKey(4)
|
||||
a := make([]*big.Int, 4)
|
||||
b := make([]*big.Int, 4)
|
||||
|
||||
a[0] = big.NewInt(1)
|
||||
a[1] = big.NewInt(1)
|
||||
a[2] = big.NewInt(1)
|
||||
a[3] = big.NewInt(1)
|
||||
|
||||
b[0] = big.NewInt(1)
|
||||
b[1] = big.NewInt(1)
|
||||
b[2] = big.NewInt(1)
|
||||
b[3] = big.NewInt(1)
|
||||
|
||||
c := InnerProduct(a, b)
|
||||
|
||||
P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
|
||||
|
||||
ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
|
||||
|
||||
if InnerProductVerify(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
|
||||
fmt.Println("Inner Product Proof correct")
|
||||
} else {
|
||||
t.Error("Inner Product Proof incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInnerProductProveLen8(t *testing.T) {
|
||||
fmt.Println("TestInnerProductProve8")
|
||||
EC = genECPrimeGroupKey(8)
|
||||
a := make([]*big.Int, 8)
|
||||
b := make([]*big.Int, 8)
|
||||
|
||||
a[0] = big.NewInt(1)
|
||||
a[1] = big.NewInt(1)
|
||||
a[2] = big.NewInt(1)
|
||||
a[3] = big.NewInt(1)
|
||||
a[4] = big.NewInt(1)
|
||||
a[5] = big.NewInt(1)
|
||||
a[6] = big.NewInt(1)
|
||||
a[7] = big.NewInt(1)
|
||||
|
||||
b[0] = big.NewInt(2)
|
||||
b[1] = big.NewInt(2)
|
||||
b[2] = big.NewInt(2)
|
||||
b[3] = big.NewInt(2)
|
||||
b[4] = big.NewInt(2)
|
||||
b[5] = big.NewInt(2)
|
||||
b[6] = big.NewInt(2)
|
||||
b[7] = big.NewInt(2)
|
||||
|
||||
c := InnerProduct(a, b)
|
||||
|
||||
P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
|
||||
|
||||
ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
|
||||
|
||||
if InnerProductVerify(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
|
||||
fmt.Println("Inner Product Proof correct")
|
||||
} else {
|
||||
t.Error("Inner Product Proof incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInnerProductProveLen64Rand(t *testing.T) {
|
||||
fmt.Println("TestInnerProductProveLen64Rand")
|
||||
EC = genECPrimeGroupKey(64)
|
||||
a := RandVector(64)
|
||||
b := RandVector(64)
|
||||
|
||||
c := InnerProduct(a, b)
|
||||
|
||||
P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
|
||||
|
||||
ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
|
||||
|
||||
if InnerProductVerify(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
|
||||
fmt.Println("Inner Product Proof correct")
|
||||
} else {
|
||||
t.Error("Inner Product Proof incorrect")
|
||||
fmt.Printf("Values Used: \n\ta = %s\n\tb = %s\n", a, b)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestInnerProductVerifyFastLen1(t *testing.T) {
|
||||
fmt.Println("TestInnerProductProve1")
|
||||
EC = genECPrimeGroupKey(1)
|
||||
a := make([]*big.Int, 1)
|
||||
b := make([]*big.Int, 1)
|
||||
|
||||
a[0] = big.NewInt(2)
|
||||
|
||||
b[0] = big.NewInt(2)
|
||||
|
||||
c := InnerProduct(a, b)
|
||||
|
||||
P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
|
||||
|
||||
ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
|
||||
|
||||
if InnerProductVerifyFast(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
|
||||
fmt.Println("Inner Product Proof correct")
|
||||
} else {
|
||||
t.Error("Inner Product Proof incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInnerProductVerifyFastLen2(t *testing.T) {
|
||||
fmt.Println("TestInnerProductProve2")
|
||||
EC = genECPrimeGroupKey(2)
|
||||
a := make([]*big.Int, 2)
|
||||
b := make([]*big.Int, 2)
|
||||
|
||||
a[0] = big.NewInt(2)
|
||||
a[1] = big.NewInt(3)
|
||||
|
||||
b[0] = big.NewInt(2)
|
||||
b[1] = big.NewInt(3)
|
||||
|
||||
c := InnerProduct(a, b)
|
||||
|
||||
P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
|
||||
|
||||
ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
|
||||
|
||||
if InnerProductVerifyFast(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
|
||||
fmt.Println("Inner Product Proof correct")
|
||||
} else {
|
||||
t.Error("Inner Product Proof incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInnerProductVerifyFastLen4(t *testing.T) {
|
||||
fmt.Println("TestInnerProductProve4")
|
||||
EC = genECPrimeGroupKey(4)
|
||||
a := make([]*big.Int, 4)
|
||||
b := make([]*big.Int, 4)
|
||||
|
||||
a[0] = big.NewInt(1)
|
||||
a[1] = big.NewInt(1)
|
||||
a[2] = big.NewInt(1)
|
||||
a[3] = big.NewInt(1)
|
||||
|
||||
b[0] = big.NewInt(1)
|
||||
b[1] = big.NewInt(1)
|
||||
b[2] = big.NewInt(1)
|
||||
b[3] = big.NewInt(1)
|
||||
|
||||
c := InnerProduct(a, b)
|
||||
|
||||
P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
|
||||
|
||||
ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
|
||||
|
||||
if InnerProductVerifyFast(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
|
||||
fmt.Println("Inner Product Proof correct")
|
||||
} else {
|
||||
t.Error("Inner Product Proof incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInnerProductVerifyFastLen8(t *testing.T) {
|
||||
fmt.Println("TestInnerProductProve8")
|
||||
EC = genECPrimeGroupKey(8)
|
||||
a := make([]*big.Int, 8)
|
||||
b := make([]*big.Int, 8)
|
||||
|
||||
a[0] = big.NewInt(1)
|
||||
a[1] = big.NewInt(1)
|
||||
a[2] = big.NewInt(1)
|
||||
a[3] = big.NewInt(1)
|
||||
a[4] = big.NewInt(1)
|
||||
a[5] = big.NewInt(1)
|
||||
a[6] = big.NewInt(1)
|
||||
a[7] = big.NewInt(1)
|
||||
|
||||
b[0] = big.NewInt(2)
|
||||
b[1] = big.NewInt(2)
|
||||
b[2] = big.NewInt(2)
|
||||
b[3] = big.NewInt(2)
|
||||
b[4] = big.NewInt(2)
|
||||
b[5] = big.NewInt(2)
|
||||
b[6] = big.NewInt(2)
|
||||
b[7] = big.NewInt(2)
|
||||
|
||||
c := InnerProduct(a, b)
|
||||
|
||||
P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
|
||||
|
||||
ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
|
||||
|
||||
if InnerProductVerifyFast(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
|
||||
fmt.Println("Inner Product Proof correct")
|
||||
} else {
|
||||
t.Error("Inner Product Proof incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInnerProductVerifyFastLen64Rand(t *testing.T) {
|
||||
fmt.Println("TestInnerProductProveLen64Rand")
|
||||
EC = genECPrimeGroupKey(64)
|
||||
a := RandVector(64)
|
||||
b := RandVector(64)
|
||||
|
||||
c := InnerProduct(a, b)
|
||||
|
||||
P := TwoVectorPCommitWithGens(EC.BPG, EC.BPH, a, b)
|
||||
|
||||
ipp := InnerProductProve(a, b, c, P, EC.U, EC.BPG, EC.BPH)
|
||||
|
||||
if InnerProductVerifyFast(c, P, EC.U, EC.BPG, EC.BPH, ipp) {
|
||||
fmt.Println("Inner Product Proof correct")
|
||||
} else {
|
||||
t.Error("Inner Product Proof incorrect")
|
||||
fmt.Printf("Values Used: \n\ta = %s\n\tb = %s\n", a, b)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMRPProveZERO(t *testing.T) {
|
||||
|
||||
mRangeProof, _ := MRPProve([]*big.Int{
|
||||
new(big.Int).SetInt64(0),
|
||||
})
|
||||
mv := MRPVerify(&mRangeProof)
|
||||
assert.Equal(t, mv, true, " MRProof incorrect")
|
||||
}
|
||||
|
||||
func TestMRPProve_MAX_2_POW_64(t *testing.T) {
|
||||
|
||||
mRangeProof, _ := MRPProve([]*big.Int{
|
||||
new(big.Int).SetUint64(0xFFFFFFFFFFFFFFFF),
|
||||
})
|
||||
mv := MRPVerify(&mRangeProof)
|
||||
assert.Equal(t, mv, true, " MRProof incorrect")
|
||||
}
|
||||
|
||||
func TestMRPProveOutOfSupportedRange(t *testing.T) {
|
||||
|
||||
value, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFF", 16)
|
||||
_, err := MRPProve([]*big.Int{
|
||||
value,
|
||||
})
|
||||
assert.NotNil(t, err, " MRProof incorrect")
|
||||
}
|
||||
|
||||
func TestMRPProve_RANDOM(t *testing.T) {
|
||||
|
||||
mRangeProof, _ := MRPProve(Rand64Vector(1))
|
||||
mv := MRPVerify(&mRangeProof)
|
||||
assert.Equal(t, mv, true, " MRProof incorrect")
|
||||
|
||||
mRangeProof, _ = MRPProve(Rand64Vector(2))
|
||||
mv = MRPVerify(&mRangeProof)
|
||||
assert.Equal(t, mv, true, " MRProof incorrect")
|
||||
|
||||
mRangeProof, _ = MRPProve(Rand64Vector(4))
|
||||
mv = MRPVerify(&mRangeProof)
|
||||
assert.Equal(t, mv, true, " MRProof incorrect")
|
||||
|
||||
mRangeProof, _ = MRPProve(Rand64Vector(8))
|
||||
mv = MRPVerify(&mRangeProof)
|
||||
assert.Equal(t, mv, true, " MRProof incorrect")
|
||||
}
|
||||
|
||||
func Rand64Vector(l int) []*big.Int {
|
||||
result := make([]*big.Int, l)
|
||||
|
||||
for i := 0; i < l; i++ {
|
||||
x, err := rand.Int(rand.Reader, big.NewInt(0xFFFFFFFFFFFFFFF))
|
||||
check(err)
|
||||
result[i] = x
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func TestMRPProveValueNumberNotSupported(t *testing.T) {
|
||||
|
||||
_, err := MRPProve(Rand64Vector(3))
|
||||
assert.NotNil(t, err, "MRProof incorrect - accepted 3 inputs")
|
||||
|
||||
_, err = MRPProve(Rand64Vector(5))
|
||||
assert.NotNil(t, err, "MRProof incorrect - accepted 5 inputs")
|
||||
|
||||
_, err = MRPProve(Rand64Vector(6))
|
||||
assert.NotNil(t, err, "MRProof incorrect - accepted 6 inputs")
|
||||
|
||||
_, err = MRPProve(Rand64Vector(7))
|
||||
assert.NotNil(t, err, "MRProof incorrect - accepted 7 inputs")
|
||||
|
||||
_, err = MRPProve(Rand64Vector(10))
|
||||
assert.NotNil(t, err, "MRProof incorrect - accepted 10 inputs")
|
||||
|
||||
_, err = MRPProve(Rand64Vector(1))
|
||||
assert.Nil(t, err, "MRProof incorrect - not accepted 1 inputs")
|
||||
|
||||
_, err = MRPProve(Rand64Vector(2))
|
||||
assert.Nil(t, err, "MRProof incorrect - not accepted 2 inputs")
|
||||
|
||||
_, err = MRPProve(Rand64Vector(4))
|
||||
fmt.Println(err)
|
||||
assert.Nil(t, err, "MRProof incorrect - not accepted 4 inputs")
|
||||
|
||||
_, err = MRPProve(Rand64Vector(8))
|
||||
assert.Nil(t, err, "MRProof incorrect - not accepted 8 inputs")
|
||||
}
|
||||
|
||||
type Point struct {
|
||||
x string
|
||||
y string
|
||||
}
|
||||
|
||||
type IPP struct {
|
||||
L []map[string]string `json:"L"`
|
||||
R []map[string]string `json:"R"`
|
||||
A string `json:"A"`
|
||||
B string `json:"B"`
|
||||
Challenges []string `json:"Challenges"`
|
||||
}
|
||||
|
||||
type BulletProof struct {
|
||||
Comms []string `json:"Comms"`
|
||||
A string `json:"A"`
|
||||
S string `json:"S"`
|
||||
Cx string `json:"Cx"`
|
||||
Cy string `json:"Cy"`
|
||||
Cz string `json:"Cz"`
|
||||
T1 string `json:"T1"`
|
||||
T2 string `json:"T2"`
|
||||
Th string `json:"Th"`
|
||||
Tau string `json:"Tau"`
|
||||
Mu string `json:"Mu"`
|
||||
Ipp IPP `json:"Ipp"`
|
||||
}
|
||||
|
||||
func parseTestData(filePath string) MultiRangeProof {
|
||||
jsonFile, err := os.Open(filePath)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
defer jsonFile.Close()
|
||||
|
||||
byteValue, _ := io.ReadAll(jsonFile)
|
||||
|
||||
// we initialize our Users array
|
||||
// var result map[string]interface{}
|
||||
result := BulletProof{}
|
||||
|
||||
json.Unmarshal([]byte(byteValue), &result)
|
||||
|
||||
fmt.Println("result ", result.Tau)
|
||||
fmt.Println("result ", result.Th)
|
||||
fmt.Println("result.Ipp ", result.Ipp)
|
||||
|
||||
ipp := result.Ipp
|
||||
|
||||
proof := MultiRangeProof{
|
||||
Comms: MapECPointFromHex(result.Comms, ECPointFromHex),
|
||||
A: ECPointFromHex(result.A),
|
||||
S: ECPointFromHex(result.S),
|
||||
T1: ECPointFromHex(result.T1),
|
||||
T2: ECPointFromHex(result.T2),
|
||||
Th: bigIFromHex(result.Th),
|
||||
Tau: bigIFromHex(result.Tau),
|
||||
Mu: bigIFromHex(result.Mu),
|
||||
Cx: bigIFromHex(result.Cx),
|
||||
Cy: bigIFromHex(result.Cy),
|
||||
Cz: bigIFromHex(result.Cz),
|
||||
IPP: InnerProdArg{
|
||||
L: MapECPoint(ipp.L, ECPointFromPoint),
|
||||
R: MapECPoint(ipp.R, ECPointFromPoint),
|
||||
A: bigIFromHex(ipp.A),
|
||||
B: bigIFromHex(ipp.B),
|
||||
Challenges: MapBigI(ipp.Challenges, bigIFromHex),
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Println(proof)
|
||||
return proof
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
Utils for parsing data from json
|
||||
*/
|
||||
func MapBigI(list []string, f func(string) *big.Int) []*big.Int {
|
||||
result := make([]*big.Int, len(list))
|
||||
|
||||
for i, item := range list {
|
||||
result[i] = f(item)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func MapECPointFromHex(list []string, f func(string) ECPoint) []ECPoint {
|
||||
result := make([]ECPoint, len(list))
|
||||
|
||||
for i, item := range list {
|
||||
result[i] = f(item)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func MapECPoint(list []map[string]string, f func(Point) ECPoint) []ECPoint {
|
||||
result := make([]ECPoint, len(list))
|
||||
|
||||
for i, item := range list {
|
||||
result[i] = f(Point{
|
||||
x: item["x"],
|
||||
y: item["y"],
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func bigIFromHex(hex string) *big.Int {
|
||||
tmp, _ := new(big.Int).SetString(hex, 16)
|
||||
return tmp
|
||||
}
|
||||
|
||||
func ECPointFromHex(hex string) ECPoint {
|
||||
Px, _ := new(big.Int).SetString(hex[:64], 16)
|
||||
Py, _ := new(big.Int).SetString(hex[64:], 16)
|
||||
P := ECPoint{Px, Py}
|
||||
return P
|
||||
}
|
||||
|
||||
func ECPointFromPoint(ecpoint Point) ECPoint {
|
||||
Px, _ := new(big.Int).SetString(ecpoint.x, 16)
|
||||
Py, _ := new(big.Int).SetString(ecpoint.y, 16)
|
||||
P := ECPoint{Px, Py}
|
||||
return P
|
||||
}
|
||||
|
||||
func TestMRPGeneration(t *testing.T) {
|
||||
values := make([]*big.Int, 2)
|
||||
values[0] = big.NewInt(1000)
|
||||
values[1] = big.NewInt(100000)
|
||||
mrp, err := MRPProve(values)
|
||||
if err != nil {
|
||||
t.Error("failed to generate bulletproof")
|
||||
}
|
||||
|
||||
v := MRPVerify(&mrp)
|
||||
serilizedBp := mrp.Serialize()
|
||||
|
||||
newMRP := new(MultiRangeProof)
|
||||
if newMRP.Deserialize(serilizedBp) != nil {
|
||||
t.Error("failed to deserialized bulletproof")
|
||||
}
|
||||
|
||||
v = v && MRPVerify(newMRP)
|
||||
|
||||
if !v {
|
||||
t.Error("failed to verify bulletproof")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,632 +0,0 @@
|
|||
package privacy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto/secp256k1"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/log"
|
||||
)
|
||||
|
||||
// These constants define the lengths of serialized public keys.
|
||||
const (
|
||||
PubKeyBytesLenCompressed = 33
|
||||
PubKeyBytesLenUncompressed = 65
|
||||
PubKeyBytesLenHybrid = 65
|
||||
)
|
||||
|
||||
const (
|
||||
pubkeyCompressed byte = 0x2 // y_bit + x coord
|
||||
pubkeyUncompressed byte = 0x4 // x coord + y coord
|
||||
pubkeyHybrid byte = 0x6 // y_bit + x coord + y coord
|
||||
)
|
||||
|
||||
// The proof contains pretty much stuffs
|
||||
// The proof contains pretty much stuffs
|
||||
// Ring size rs: 1 byte => proof[0]
|
||||
// num input: number of real inputs: 1 byte => proof[1]
|
||||
// List of inputs/UTXO index typed uint64 => total size = rs * numInput * 8 = proof[0]*proof[1]*8
|
||||
// List of key images: total size = numInput * 33 = proof[1] * 33
|
||||
// number of output n: 1 byte
|
||||
// List of output => n * 130 bytes
|
||||
// transaction fee: uint256 => 32 byte
|
||||
// ringCT proof size ctSize: uint16 => 2 byte
|
||||
// ringCT proof: ctSize bytes
|
||||
// bulletproofs: bp
|
||||
type PrivateSendVerifier struct {
|
||||
proof []byte
|
||||
//ringCT RingCT
|
||||
}
|
||||
|
||||
type Ring []*ecdsa.PublicKey
|
||||
|
||||
type RingSignature struct {
|
||||
NumRing int
|
||||
Size int // size of ring
|
||||
M [32]byte // message
|
||||
C *big.Int // ring signature value, 1 element
|
||||
S [][]*big.Int // ring signature values: [NumRing][Size]
|
||||
Ring []Ring // array of rings of pubkeys: [NumRing]
|
||||
I []*ecdsa.PublicKey // key images, size = the number of rings [NumRing]
|
||||
Curve elliptic.Curve
|
||||
SerializedRing []byte //temporary memory stored the raw ring ct used in case of verifying ringCT with message verification
|
||||
}
|
||||
|
||||
func (p *PrivateSendVerifier) verify() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *PrivateSendVerifier) deserialize() {
|
||||
|
||||
}
|
||||
|
||||
// helper function, returns type of v
|
||||
func typeof(v interface{}) string {
|
||||
return fmt.Sprintf("%T", v)
|
||||
}
|
||||
|
||||
func isOdd(a *big.Int) bool {
|
||||
return a.Bit(0) == 1
|
||||
}
|
||||
|
||||
// SerializeCompressed serializes a public key in a 33-byte compressed format.
|
||||
func SerializeCompressed(p *ecdsa.PublicKey) []byte {
|
||||
b := make([]byte, 0, PubKeyBytesLenCompressed)
|
||||
format := pubkeyCompressed
|
||||
if isOdd(p.Y) {
|
||||
format |= 0x1
|
||||
}
|
||||
b = append(b, format)
|
||||
return append(b, PadTo32Bytes(p.X.Bytes())...)
|
||||
}
|
||||
|
||||
func DeserializeCompressed(curve elliptic.Curve, b []byte) *ecdsa.PublicKey {
|
||||
x := new(big.Int).SetBytes(b[1:33])
|
||||
// Y = +-sqrt(x^3 + B)
|
||||
x3 := new(big.Int).Mul(x, x)
|
||||
x3.Mul(x3, x)
|
||||
x3.Add(x3, curve.Params().B)
|
||||
|
||||
// now calculate sqrt mod p of x2 + B
|
||||
// This code used to do a full sqrt based on tonelli/shanks,
|
||||
// but this was replaced by the algorithms referenced in
|
||||
// https://bitcointalk.org/index.php?topic=162805.msg1712294#msg1712294
|
||||
PPlus1Div4 := new(big.Int).Add(curve.Params().P, big.NewInt(1))
|
||||
PPlus1Div4 = PPlus1Div4.Div(PPlus1Div4, big.NewInt(4))
|
||||
y := new(big.Int).Exp(x3, PPlus1Div4, curve.Params().P)
|
||||
ybit := b[0]%2 == 1
|
||||
if ybit != isOdd(y) {
|
||||
y.Sub(curve.Params().P, y)
|
||||
}
|
||||
if ybit != isOdd(y) {
|
||||
return nil
|
||||
}
|
||||
return &ecdsa.PublicKey{curve, x, y}
|
||||
}
|
||||
|
||||
// bytes returns the public key ring as a byte slice.
|
||||
func (r Ring) Bytes() (b []byte) {
|
||||
for _, pub := range r {
|
||||
b = append(b, PadTo32Bytes(pub.X.Bytes())...)
|
||||
b = append(b, PadTo32Bytes(pub.Y.Bytes())...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func PadTo32Bytes(in []byte) []byte {
|
||||
padded := make([]byte, 32)
|
||||
if len(in) >= 32 {
|
||||
copy(padded, in)
|
||||
} else {
|
||||
copy(padded[32-len(in):], in)
|
||||
}
|
||||
|
||||
return padded
|
||||
}
|
||||
|
||||
// converts the signature to a byte array
|
||||
// this is the format that will be used when passing EVM bytecode
|
||||
func (r *RingSignature) Serialize() ([]byte, error) {
|
||||
sig := []byte{}
|
||||
// add size and message
|
||||
b := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, uint64(r.NumRing))
|
||||
sig = append(sig, b[:]...) // 8 bytes
|
||||
|
||||
b = make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(b, uint64(r.Size))
|
||||
sig = append(sig, b[:]...) // 8 bytes
|
||||
|
||||
sig = append(sig, PadTo32Bytes(r.M[:])...) // 32 bytes
|
||||
sig = append(sig, PadTo32Bytes(r.C.Bytes())...) // 32 bytes
|
||||
|
||||
for k := 0; k < r.NumRing; k++ {
|
||||
// 96 bytes each iteration
|
||||
for i := 0; i < r.Size; i++ {
|
||||
sig = append(sig, PadTo32Bytes(r.S[k][i].Bytes())...)
|
||||
}
|
||||
}
|
||||
for k := 0; k < r.NumRing; k++ {
|
||||
// 96 bytes each iteration
|
||||
for i := 0; i < r.Size; i++ {
|
||||
rb := SerializeCompressed(r.Ring[k][i])
|
||||
sig = append(sig, rb...)
|
||||
}
|
||||
}
|
||||
|
||||
for k := 0; k < r.NumRing; k++ {
|
||||
// 64 bytes
|
||||
rb := SerializeCompressed(r.I[k])
|
||||
sig = append(sig, rb...)
|
||||
}
|
||||
|
||||
if len(sig) != 8+8+32+32+(32+33)*r.NumRing*r.Size+33*r.NumRing {
|
||||
return []byte{}, errors.New("Could not serialize ring signature")
|
||||
}
|
||||
|
||||
return sig, nil
|
||||
}
|
||||
|
||||
func computeSignatureSize(numRing int, ringSize int) int {
|
||||
const MaxInt = int(^uint(0) >> 1)
|
||||
|
||||
if numRing < 0 || ringSize < 0 {
|
||||
return -1
|
||||
}
|
||||
|
||||
// Calculate term and check for overflow
|
||||
|
||||
term := numRing * ringSize * 65
|
||||
|
||||
if term < 0 || term < numRing || term < ringSize {
|
||||
return -1
|
||||
}
|
||||
|
||||
return 8 + 8 + 32 + 32 + numRing*ringSize*32 + numRing*ringSize*33 + numRing*33
|
||||
}
|
||||
|
||||
// deserializes the byteified signature into a RingSignature struct
|
||||
func Deserialize(r []byte) (*RingSignature, error) {
|
||||
if len(r) < 16 {
|
||||
return nil, errors.New("Failed to deserialize ring signature")
|
||||
}
|
||||
offset := 0
|
||||
sig := new(RingSignature)
|
||||
numRing := r[offset : offset+8]
|
||||
offset += 8
|
||||
size := r[offset : offset+8]
|
||||
offset += 8
|
||||
|
||||
size_uint := binary.BigEndian.Uint64(size)
|
||||
size_int := int(size_uint)
|
||||
sig.Size = size_int
|
||||
|
||||
size_uint = binary.BigEndian.Uint64(numRing)
|
||||
size_int = int(size_uint)
|
||||
sig.NumRing = size_int
|
||||
|
||||
if len(r) != computeSignatureSize(sig.NumRing, sig.Size) {
|
||||
return nil, fmt.Errorf("incorrect ring size, len r: %d, sig.NumRing: %d sig.Size: %d", len(r), sig.NumRing, sig.Size)
|
||||
}
|
||||
|
||||
m := r[offset : offset+32]
|
||||
offset += 32
|
||||
|
||||
var m_byte [32]byte
|
||||
copy(m_byte[:], m)
|
||||
|
||||
sig.M = m_byte
|
||||
sig.C = new(big.Int).SetBytes(r[offset : offset+32])
|
||||
offset += 32
|
||||
|
||||
sig.S = make([][]*big.Int, sig.NumRing)
|
||||
for i := 0; i < sig.NumRing; i++ {
|
||||
sig.S[i] = make([]*big.Int, sig.Size)
|
||||
for j := 0; j < sig.Size; j++ {
|
||||
sig.S[i][j] = new(big.Int).SetBytes(r[offset : offset+32])
|
||||
offset += 32
|
||||
}
|
||||
}
|
||||
|
||||
sig.Curve = crypto.S256()
|
||||
|
||||
sig.Ring = make([]Ring, sig.NumRing)
|
||||
for i := 0; i < sig.NumRing; i++ {
|
||||
sig.Ring[i] = make([]*ecdsa.PublicKey, sig.Size)
|
||||
for j := 0; j < sig.Size; j++ {
|
||||
compressedKey := r[offset : offset+33]
|
||||
offset += 33
|
||||
compressedPubKey := DeserializeCompressed(sig.Curve, compressedKey)
|
||||
sig.Ring[i][j] = compressedPubKey
|
||||
}
|
||||
}
|
||||
|
||||
sig.I = make([]*ecdsa.PublicKey, sig.NumRing)
|
||||
for i := 0; i < sig.NumRing; i++ {
|
||||
compressedKey := r[offset : offset+33]
|
||||
offset += 33
|
||||
compressedPubKey := DeserializeCompressed(sig.Curve, compressedKey)
|
||||
sig.I[i] = compressedPubKey
|
||||
}
|
||||
|
||||
sig.SerializedRing = r
|
||||
|
||||
if !Verify(sig, false) {
|
||||
return nil, errors.New("failed to deserialize, invalid ring signature")
|
||||
}
|
||||
|
||||
return sig, nil
|
||||
}
|
||||
|
||||
// takes public key ring and places the public key corresponding to `privkey` in index s of the ring
|
||||
// returns a key ring of type []*ecdsa.PublicKey
|
||||
func GenKeyRing(ring []*ecdsa.PublicKey, privkey *ecdsa.PrivateKey, s int) ([]*ecdsa.PublicKey, error) {
|
||||
size := len(ring) + 1
|
||||
new_ring := make([]*ecdsa.PublicKey, size)
|
||||
pubkey := privkey.Public().(*ecdsa.PublicKey)
|
||||
|
||||
if s > len(ring) {
|
||||
return nil, errors.New("index s out of bounds")
|
||||
}
|
||||
|
||||
new_ring[s] = pubkey
|
||||
for i := 1; i < size; i++ {
|
||||
idx := (i + s) % size
|
||||
new_ring[idx] = ring[i-1]
|
||||
}
|
||||
|
||||
return new_ring, nil
|
||||
}
|
||||
|
||||
// creates a ring with size specified by `size` and places the public key corresponding to `privkey` in index s of the ring
|
||||
// returns a new key ring of type []*ecdsa.PublicKey
|
||||
func GenNewKeyRing(size int, privkey *ecdsa.PrivateKey, s int) ([]*ecdsa.PublicKey, error) {
|
||||
ring := make([]*ecdsa.PublicKey, size)
|
||||
pubkey := privkey.Public().(*ecdsa.PublicKey)
|
||||
|
||||
if s >= len(ring) {
|
||||
return nil, errors.New("index s out of bounds")
|
||||
}
|
||||
|
||||
ring[s] = pubkey
|
||||
|
||||
for i := 1; i < size; i++ {
|
||||
idx := (i + s) % size
|
||||
priv, err := crypto.GenerateKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pub := priv.Public()
|
||||
ring[idx] = pub.(*ecdsa.PublicKey)
|
||||
}
|
||||
|
||||
return ring, nil
|
||||
}
|
||||
|
||||
// calculate key image I = x * H_p(P) where H_p is a hash function that returns a point
|
||||
// H_p(P) = sha3(P) * G
|
||||
func GenKeyImage(privkey *ecdsa.PrivateKey) *ecdsa.PublicKey {
|
||||
pubkey := privkey.Public().(*ecdsa.PublicKey)
|
||||
image := new(ecdsa.PublicKey)
|
||||
|
||||
// calculate sha3(P)
|
||||
h_x, h_y := HashPoint(pubkey)
|
||||
|
||||
// calculate H_p(P) = x * sha3(P) * G
|
||||
i_x, i_y := privkey.Curve.ScalarMult(h_x, h_y, privkey.D.Bytes())
|
||||
|
||||
image.X = i_x
|
||||
image.Y = i_y
|
||||
return image
|
||||
}
|
||||
|
||||
func HashPoint(p *ecdsa.PublicKey) (*big.Int, *big.Int) {
|
||||
input := append(PadTo32Bytes(p.X.Bytes()), PadTo32Bytes(p.Y.Bytes())...)
|
||||
log.Info("HashPoint", "input ", common.Bytes2Hex(input))
|
||||
hash := crypto.Keccak256(input)
|
||||
log.Info("HashPoint", "hash ", common.Bytes2Hex(hash))
|
||||
return p.Curve.ScalarBaseMult(hash[:])
|
||||
}
|
||||
|
||||
// create ring signature from list of public keys given inputs:
|
||||
// msg: byte array, message to be signed
|
||||
// ring: array of *ecdsa.PublicKeys to be included in the ring
|
||||
// privkey: *ecdsa.PrivateKey of signer
|
||||
// s: index of signer in ring
|
||||
func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingSignature, error) {
|
||||
numRing := len(rings)
|
||||
if numRing < 1 {
|
||||
return nil, errors.New("there is no ring to make signature")
|
||||
}
|
||||
// check ringsize > 1
|
||||
ringsize := len(rings[0])
|
||||
if ringsize < 2 {
|
||||
return nil, errors.New("size of ring less than two")
|
||||
} else if s >= ringsize || s < 0 {
|
||||
return nil, errors.New("secret index out of range of ring size")
|
||||
}
|
||||
|
||||
// setup
|
||||
//pubkey := privkey.Public().(*ecdsa.PublicKey)
|
||||
pubkeys := make([]*ecdsa.PublicKey, numRing)
|
||||
for i := 0; i < numRing; i++ {
|
||||
pubkeys[i] = &privkeys[i].PublicKey
|
||||
}
|
||||
//cast to BitCurve used in go-eth since elliptic.Curve.Add() and elliptic.Curve.ScalarMult() is deprecated
|
||||
curve := pubkeys[0].Curve.(*secp256k1.BitCurve)
|
||||
sig := new(RingSignature)
|
||||
sig.Size = ringsize
|
||||
sig.NumRing = numRing
|
||||
sig.M = m
|
||||
sig.Ring = rings
|
||||
sig.Curve = curve
|
||||
|
||||
// check that key at index s is indeed the signer
|
||||
for i := 0; i < numRing; i++ {
|
||||
if rings[i][s] != pubkeys[i] {
|
||||
return nil, errors.New("secret index in ring is not signer")
|
||||
}
|
||||
}
|
||||
|
||||
// generate key image
|
||||
images := make([]*ecdsa.PublicKey, numRing)
|
||||
for i := 0; i < numRing; i++ {
|
||||
images[i] = GenKeyImage(privkeys[i])
|
||||
}
|
||||
sig.I = images
|
||||
|
||||
// start at c[1]
|
||||
// pick random scalar u (glue value), calculate c[1] = H(m, u*G) where H is a hash function and G is the base point of the curve
|
||||
C := make([]*big.Int, ringsize)
|
||||
S := make([][]*big.Int, numRing)
|
||||
for i := 0; i < numRing; i++ {
|
||||
S[i] = make([]*big.Int, ringsize)
|
||||
}
|
||||
|
||||
//Initialize S except S[..][s]
|
||||
for i := 0; i < numRing; i++ {
|
||||
for j := 0; j < ringsize; j++ {
|
||||
if j != s {
|
||||
randomGenerated, err := rand.Int(rand.Reader, curve.Params().P)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
S[i][j] = randomGenerated
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
L := make([][]*ecdsa.PublicKey, numRing)
|
||||
R := make([][]*ecdsa.PublicKey, numRing)
|
||||
for i := 0; i < numRing; i++ {
|
||||
L[i] = make([]*ecdsa.PublicKey, ringsize)
|
||||
R[i] = make([]*ecdsa.PublicKey, ringsize)
|
||||
}
|
||||
alpha := make([]*big.Int, numRing)
|
||||
|
||||
var l []byte
|
||||
//compute L[i][s], R[i][s], i = 0..numRing
|
||||
for i := 0; i < numRing; i++ {
|
||||
randomGenerated, err := rand.Int(rand.Reader, curve.Params().P)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
alpha[i] = randomGenerated
|
||||
// start at secret index s/PI
|
||||
// compute L_s = u*G
|
||||
l_x, l_y := curve.ScalarBaseMult(PadTo32Bytes(alpha[i].Bytes()))
|
||||
L[i][s] = &ecdsa.PublicKey{curve, l_x, l_y}
|
||||
lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...)
|
||||
l = append(l, lT...)
|
||||
// compute R_s = u*H_p(P[s])
|
||||
h_x, h_y := HashPoint(pubkeys[i])
|
||||
r_x, r_y := curve.ScalarMult(h_x, h_y, PadTo32Bytes(alpha[i].Bytes()))
|
||||
R[i][s] = &ecdsa.PublicKey{curve, r_x, r_y}
|
||||
rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...)
|
||||
l = append(l, rT...)
|
||||
}
|
||||
|
||||
// concatenate m and u*G and calculate c[s+1] = H(m, L_s, R_s)
|
||||
C_j := crypto.Keccak256(append(m[:], l...))
|
||||
idx := s + 1
|
||||
if idx == ringsize {
|
||||
idx = 0
|
||||
}
|
||||
if idx == 0 {
|
||||
C[0] = new(big.Int).SetBytes(C_j[:])
|
||||
} else {
|
||||
C[idx] = new(big.Int).SetBytes(C_j[:])
|
||||
}
|
||||
for idx != s {
|
||||
var l []byte
|
||||
for j := 0; j < numRing; j++ {
|
||||
// calculate L[j][idx] = s[j][idx]*G + c[idx]*Ring[j][idx]
|
||||
px, py := curve.ScalarMult(rings[j][idx].X, rings[j][idx].Y, PadTo32Bytes(C[idx].Bytes())) // px, py = c_i*P_i
|
||||
sx, sy := curve.ScalarBaseMult(PadTo32Bytes(S[j][idx].Bytes())) // sx, sy = s[n-1]*G
|
||||
if px == nil || py == nil || sx == nil || sy == nil {
|
||||
return nil, errors.New("Could not create ring signature")
|
||||
}
|
||||
l_x, l_y := curve.Add(sx, sy, px, py)
|
||||
L[j][idx] = &ecdsa.PublicKey{curve, l_x, l_y}
|
||||
lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...)
|
||||
l = append(l, lT...)
|
||||
|
||||
// calculate R[j][idx] = s[j][idx]*H_p(Ring[j][idx]) + c[idx]*I[j]
|
||||
px, py = curve.ScalarMult(images[j].X, images[j].Y, C[idx].Bytes()) // px, py = c_i*I
|
||||
hx, hy := HashPoint(rings[j][idx])
|
||||
sx, sy = curve.ScalarMult(hx, hy, S[j][idx].Bytes()) // sx, sy = s[n-1]*H_p(P_i)
|
||||
if px == nil || py == nil || sx == nil || sy == nil {
|
||||
return nil, errors.New("Could not create ring signature")
|
||||
}
|
||||
r_x, r_y := curve.Add(sx, sy, px, py)
|
||||
R[j][idx] = &ecdsa.PublicKey{curve, r_x, r_y}
|
||||
rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...)
|
||||
l = append(l, rT...)
|
||||
}
|
||||
|
||||
idx++
|
||||
if idx == ringsize {
|
||||
idx = 0
|
||||
}
|
||||
|
||||
var ciIdx int
|
||||
if idx == 0 {
|
||||
ciIdx = 0
|
||||
} else {
|
||||
ciIdx = idx
|
||||
}
|
||||
cSha := crypto.Keccak256(append(PadTo32Bytes(m[:]), l...))
|
||||
C[ciIdx] = new(big.Int).SetBytes(cSha[:])
|
||||
}
|
||||
|
||||
//compute S[j][s] = alpha[j] - c[s] * privkeys[j], privkeys[j] = private key corresponding to key image I[j]
|
||||
for j := 0; j < numRing; j++ {
|
||||
cx := C[s]
|
||||
// close ring by finding S[j][s] = (alpha[j] - c[s]*privkeys[s] ) mod P where k[s] is the private key and P is the order of the curve
|
||||
S[j][s] = new(big.Int).Mod(new(big.Int).Sub(alpha[j], new(big.Int).Mul(cx, privkeys[j].D)), curve.Params().N)
|
||||
}
|
||||
|
||||
// everything ok, add values to signature
|
||||
sig.S = S
|
||||
sig.C = C[0]
|
||||
sig.NumRing = numRing
|
||||
sig.Size = ringsize
|
||||
sig.C = C[0]
|
||||
|
||||
return sig, nil
|
||||
}
|
||||
|
||||
// verify ring signature contained in RingSignature struct
|
||||
// returns true if a valid signature, false otherwise
|
||||
func Verify(sig *RingSignature, verifyMes bool) bool {
|
||||
// setup
|
||||
rings := sig.Ring
|
||||
ringsize := sig.Size
|
||||
numRing := sig.NumRing
|
||||
S := sig.S
|
||||
C := make([]*big.Int, ringsize+1)
|
||||
C[0] = sig.C
|
||||
//cast to BitCurve used in go-eth since elliptic.Curve.Add() and elliptic.Curve.ScalarMult() is deprecated
|
||||
curve := sig.Curve.(*secp256k1.BitCurve)
|
||||
image := sig.I
|
||||
|
||||
//check on curve
|
||||
for i := 0; i < numRing; i++ {
|
||||
onCurve := curve.IsOnCurve(image[i].X, image[i].Y)
|
||||
if !onCurve {
|
||||
return false
|
||||
}
|
||||
for j := 0; j < ringsize; j++ {
|
||||
onCurve := curve.IsOnCurve(rings[i][j].X, rings[i][j].Y)
|
||||
if !onCurve {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// calculate c[i+1] = H(m, s[i]*G + c[i]*P[i])
|
||||
// and c[0] = H)(m, s[n-1]*G + c[n-1]*P[n-1]) where n is the ring size
|
||||
//log.Info("C", "0", common.Bytes2Hex(C[0].Bytes()))
|
||||
for j := 0; j < ringsize; j++ {
|
||||
var l []byte
|
||||
for i := 0; i < numRing; i++ {
|
||||
// Validate S[i][j] and C[j]
|
||||
if !isValidScalar(S[i][j], curve) || !isValidScalar(C[j], curve) {
|
||||
return false // Or handle the error as required
|
||||
}
|
||||
|
||||
// calculate L[i][j] = s[i][j]*G + c[j]*Ring[i][j]
|
||||
px, py := curve.ScalarMult(rings[i][j].X, rings[i][j].Y, C[j].Bytes()) // px, py = c_i*P_i
|
||||
sx, sy := curve.ScalarBaseMult(S[i][j].Bytes()) // sx, sy = s[i]*G
|
||||
if px == nil || py == nil || sx == nil || sy == nil {
|
||||
return false
|
||||
}
|
||||
l_x, l_y := curve.Add(sx, sy, px, py)
|
||||
lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...)
|
||||
//log.Info("L[i][j]", "i", i, "j", j, "L", common.Bytes2Hex(lT))
|
||||
l = append(l, lT...)
|
||||
|
||||
// calculate R_i = s[i][j]*H_p(Ring[i][j]) + c[j]*I[j]
|
||||
px, py = curve.ScalarMult(image[i].X, image[i].Y, C[j].Bytes()) // px, py = c[i]*I
|
||||
hx, hy := HashPoint(rings[i][j])
|
||||
|
||||
// Validate S[i][j], hx, and hy
|
||||
if !isValidScalar(S[i][j], curve) || !isValidScalar(hx, curve) || !isValidScalar(hy, curve) {
|
||||
return false // Or handle the error as required
|
||||
}
|
||||
//log.Info("H[i][j]", "i", i, "j", j, "x.input", common.Bytes2Hex(rings[i][j].X.Bytes()), "y.input", common.Bytes2Hex(rings[i][j].Y.Bytes()))
|
||||
//log.Info("H[i][j]", "i", i, "j", j, "x", common.Bytes2Hex(hx.Bytes()), "y", common.Bytes2Hex(hy.Bytes()))
|
||||
sx, sy = curve.ScalarMult(hx, hy, S[i][j].Bytes()) // sx, sy = s[i]*H_p(P[i])
|
||||
if px == nil || py == nil || sx == nil || sy == nil {
|
||||
return false
|
||||
}
|
||||
r_x, r_y := curve.Add(sx, sy, px, py)
|
||||
rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...)
|
||||
//log.Info("R[i][j]", "i", i, "j", j, "L", common.Bytes2Hex(rT))
|
||||
l = append(l, rT...)
|
||||
}
|
||||
|
||||
// calculate c[i+1] = H(m, L_i, R_i)
|
||||
//cj_mes := append(PadTo32Bytes(sig.M[:]), l...)
|
||||
C_j := crypto.Keccak256(append(PadTo32Bytes(sig.M[:]), l...))
|
||||
//log.Info("C hash input", "j", j + 1, "C_input", common.Bytes2Hex(cj_mes))
|
||||
|
||||
/*if j == ringsize-1 {
|
||||
C[0] = new(big.Int).SetBytes(C_j[:])
|
||||
} else {*/
|
||||
C[j+1] = new(big.Int).SetBytes(C_j[:])
|
||||
//log.Info("C", "j", j + 1, "C", common.Bytes2Hex(C[j + 1].Bytes()))
|
||||
//}
|
||||
}
|
||||
|
||||
return bytes.Equal(sig.C.Bytes(), C[ringsize].Bytes())
|
||||
}
|
||||
|
||||
func isValidScalar(scalar *big.Int, curve elliptic.Curve) bool {
|
||||
return scalar.Sign() >= 0 && scalar.Cmp(curve.Params().N) < 0
|
||||
}
|
||||
|
||||
func Link(sig_a *RingSignature, sig_b *RingSignature) bool {
|
||||
for i := 0; i < len(sig_a.I); i++ {
|
||||
for j := 0; j < len(sig_b.I); j++ {
|
||||
if sig_a.I[i].X == sig_b.I[j].X && sig_a.I[i].Y == sig_b.I[j].Y {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// function returns(mutiple rings, private keys, message, error)
|
||||
func GenerateMultiRingParams(numRing int, ringSize int, s int) (rings []Ring, privkeys []*ecdsa.PrivateKey, m [32]byte, err error) {
|
||||
for i := 0; i < numRing; i++ {
|
||||
privkey, err := crypto.GenerateKey()
|
||||
if err != nil {
|
||||
return nil, nil, [32]byte{}, err
|
||||
}
|
||||
privkeys = append(privkeys, privkey)
|
||||
|
||||
ring, err := GenNewKeyRing(ringSize, privkey, s)
|
||||
if err != nil {
|
||||
return nil, nil, [32]byte{}, err
|
||||
}
|
||||
rings = append(rings, ring)
|
||||
}
|
||||
|
||||
_, err = rand.Read(m[:])
|
||||
if err != nil {
|
||||
return nil, nil, [32]byte{}, err
|
||||
}
|
||||
return rings, privkeys, m, nil
|
||||
}
|
||||
|
|
@ -1,324 +0,0 @@
|
|||
package privacy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto/secp256k1"
|
||||
)
|
||||
|
||||
func TestSign(t *testing.T) {
|
||||
/*for i := 14; i < 15; i++ {
|
||||
for j := 14; j < 15; j++ {
|
||||
for k := 0; k <= j; k++ {*/
|
||||
numRing := 5
|
||||
ringSize := 10
|
||||
s := 9
|
||||
fmt.Println("Generate random ring parameter ")
|
||||
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||
|
||||
fmt.Println("numRing ", numRing)
|
||||
fmt.Println("ringSize ", ringSize)
|
||||
fmt.Println("index of real one ", s)
|
||||
|
||||
fmt.Println("Ring ", rings)
|
||||
fmt.Println("privkeys ", privkeys)
|
||||
fmt.Println("m ", m)
|
||||
|
||||
ringSignature, err := Sign(m, rings, privkeys, s)
|
||||
if err != nil {
|
||||
t.Error("Failed to create Ring signature")
|
||||
}
|
||||
|
||||
sig, err := ringSignature.Serialize()
|
||||
if err != nil {
|
||||
t.Error("Failed to Serialize input Ring signature")
|
||||
}
|
||||
|
||||
deserializedSig, err := Deserialize(sig)
|
||||
if err != nil {
|
||||
t.Error("Failed to Deserialize Ring signature")
|
||||
}
|
||||
verified := Verify(deserializedSig, false)
|
||||
|
||||
if !verified {
|
||||
t.Error("Failed to verify Ring signature")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDeserialize(t *testing.T) {
|
||||
numRing := 5
|
||||
ringSize := 10
|
||||
s := 5
|
||||
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||
|
||||
ringSignature, err := Sign(m, rings, privkeys, s)
|
||||
if err != nil {
|
||||
t.Error("Failed to create Ring signature")
|
||||
}
|
||||
|
||||
// A normal signature.
|
||||
sig, err := ringSignature.Serialize()
|
||||
if err != nil {
|
||||
t.Error("Failed to Serialize input Ring signature")
|
||||
}
|
||||
|
||||
// Modify the serialized signature s.t.
|
||||
// the new signature passes the length check
|
||||
// but triggers buffer overflow in Deserialize().
|
||||
// ringSize: 10 -> 56759212534490939
|
||||
// len(sig): 3495 -> 3804
|
||||
// 80 + 5 * (56759212534490939*65 + 33) = 18446744073709551616 + 3804
|
||||
bs := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(bs, 56759212534490939)
|
||||
for i := 0; i < 8; i++ {
|
||||
sig[i+8] = bs[i]
|
||||
}
|
||||
tail := make([]byte, 3804-len(sig))
|
||||
sig = append(sig, tail...)
|
||||
|
||||
_, err = Deserialize(sig)
|
||||
assert.EqualError(t, err, "incorrect ring size, len r: 3804, sig.NumRing: 5 sig.Size: 56759212534490939")
|
||||
}
|
||||
|
||||
func TestVerify1(t *testing.T) {
|
||||
numRing := 5
|
||||
ringSize := 10
|
||||
s := 7
|
||||
|
||||
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||
if err != nil {
|
||||
t.Error("fail to generate rings")
|
||||
}
|
||||
|
||||
ringSignature, err := Sign(m, rings, privkeys, s)
|
||||
if err != nil {
|
||||
t.Error("fail to create ring signature")
|
||||
}
|
||||
|
||||
sig, err := ringSignature.Serialize()
|
||||
if err != nil {
|
||||
t.Error("fail to serialize input ring signature")
|
||||
}
|
||||
|
||||
deserializedSig, err := Deserialize(sig)
|
||||
if err != nil {
|
||||
t.Error("fail to deserialize ring signature")
|
||||
}
|
||||
|
||||
assert.True(t, Verify(deserializedSig, false), "Verify should return true")
|
||||
}
|
||||
|
||||
func TestDeserialize2(t *testing.T) {
|
||||
numRing := 5
|
||||
ringSize := 10
|
||||
s := 7
|
||||
|
||||
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||
if err != nil {
|
||||
t.Error("fail to generate rings")
|
||||
}
|
||||
|
||||
ringSignature, err := Sign(m, rings, privkeys, s)
|
||||
if err != nil {
|
||||
t.Error("fail to create ring signature")
|
||||
}
|
||||
|
||||
// change one sig to the scalar field
|
||||
ringSignature.S[0][0] = curve.Params().N
|
||||
|
||||
sig, err := ringSignature.Serialize()
|
||||
if err != nil {
|
||||
t.Error("fail to serialize input ring signature")
|
||||
}
|
||||
|
||||
_, err = Deserialize(sig)
|
||||
assert.EqualError(t, err, "failed to deserialize, invalid ring signature")
|
||||
}
|
||||
|
||||
func TestPadTo32Bytes(t *testing.T) {
|
||||
arr := [44]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34}
|
||||
|
||||
// test input slice is longer than 32 bytes
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[0:]), arr[0:32]), "Test PadTo32Bytes longer than 32 bytes #1")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[1:]), arr[1:33]), "Test PadTo32Bytes longer than 32 bytes #2")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[2:]), arr[2:34]), "Test PadTo32Bytes longer than 32 bytes #3")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[3:]), arr[3:35]), "Test PadTo32Bytes longer than 32 bytes #4")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[4:]), arr[4:36]), "Test PadTo32Bytes longer than 32 bytes #5")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[5:]), arr[5:37]), "Test PadTo32Bytes longer than 32 bytes #6")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[6:]), arr[6:38]), "Test PadTo32Bytes longer than 32 bytes #7")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[7:]), arr[7:39]), "Test PadTo32Bytes longer than 32 bytes #8")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[8:]), arr[8:40]), "Test PadTo32Bytes longer than 32 bytes #9")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[9:]), arr[9:41]), "Test PadTo32Bytes longer than 32 bytes #10")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:]), arr[10:42]), "Test PadTo32Bytes longer than 32 bytes #11")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[11:]), arr[11:43]), "Test PadTo32Bytes longer than 32 bytes #12")
|
||||
|
||||
// test input slice is equal 32 bytes
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[0:32]), arr[0:32]), "Test PadTo32Bytes equal 32 bytes #1")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[1:33]), arr[1:33]), "Test PadTo32Bytes equal 32 bytes #2")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[2:34]), arr[2:34]), "Test PadTo32Bytes equal 32 bytes #3")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[3:35]), arr[3:35]), "Test PadTo32Bytes equal 32 bytes #4")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[4:36]), arr[4:36]), "Test PadTo32Bytes equal 32 bytes #5")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[5:37]), arr[5:37]), "Test PadTo32Bytes equal 32 bytes #6")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[6:38]), arr[6:38]), "Test PadTo32Bytes equal 32 bytes #7")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[7:39]), arr[7:39]), "Test PadTo32Bytes equal 32 bytes #8")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[8:40]), arr[8:40]), "Test PadTo32Bytes equal 32 bytes #9")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[9:41]), arr[9:41]), "Test PadTo32Bytes equal 32 bytes #10")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:42]), arr[10:42]), "Test PadTo32Bytes equal 32 bytes #11")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[11:43]), arr[11:43]), "Test PadTo32Bytes equal 32 bytes #12")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[12:44]), arr[12:44]), "Test PadTo32Bytes equal 32 bytes #13")
|
||||
|
||||
// test input slice is shorter than 32 bytes
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:32]), arr[0:32]), "Test PadTo32Bytes shorter than 32 bytes #1")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:33]), arr[1:33]), "Test PadTo32Bytes shorter than 32 bytes #2")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:34]), arr[2:34]), "Test PadTo32Bytes shorter than 32 bytes #3")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:35]), arr[3:35]), "Test PadTo32Bytes shorter than 32 bytes #4")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:36]), arr[4:36]), "Test PadTo32Bytes shorter than 32 bytes #5")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:37]), arr[5:37]), "Test PadTo32Bytes shorter than 32 bytes #6")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:38]), arr[6:38]), "Test PadTo32Bytes shorter than 32 bytes #7")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:39]), arr[7:39]), "Test PadTo32Bytes shorter than 32 bytes #8")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:40]), arr[8:40]), "Test PadTo32Bytes shorter than 32 bytes #9")
|
||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:41]), arr[9:41]), "Test PadTo32Bytes shorter than 32 bytes #10")
|
||||
}
|
||||
|
||||
func TestCurveAddNegative(t *testing.T) {
|
||||
curve := crypto.S256().(*secp256k1.BitCurve)
|
||||
|
||||
x1, y1 := curve.ScalarBaseMult(new(big.Int).SetUint64(uint64(2)).Bytes())
|
||||
fmt.Printf("Point(%x, %x)\n", x1, y1)
|
||||
|
||||
x2 := x1
|
||||
y2 := new(big.Int).Neg(y1) // negative of point (x1,y1)
|
||||
|
||||
x3, y3 := curve.Add(x1, y1, x2, y2)
|
||||
fmt.Printf("Output is Point(%x, %x)\n", x3, y3)
|
||||
|
||||
x0 := new(big.Int).SetUint64(uint64(0))
|
||||
y0 := new(big.Int).SetUint64(uint64(0)) // infinity
|
||||
|
||||
if (x3.Cmp(x0) == 0) && (y3.Cmp(y0) == 0) {
|
||||
// fmt.Printf("Correct, add negative of self should yield (0,0)")
|
||||
} else {
|
||||
t.Error("Incorrect, add negative of self did not yield (0,0)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurveAddZero(t *testing.T) {
|
||||
// curve := crypto.S256()
|
||||
curve := crypto.S256().(*secp256k1.BitCurve)
|
||||
|
||||
x1, y1 := curve.ScalarBaseMult(new(big.Int).SetUint64(uint64(1)).Bytes())
|
||||
fmt.Printf("Point(%x, %x)\n", x1, y1)
|
||||
|
||||
x0 := new(big.Int).SetUint64(uint64(0))
|
||||
y0 := new(big.Int).SetUint64(uint64(0)) // infinity
|
||||
fmt.Printf("Is point (%d,%d) on the curve: %t \n", x0, y0, curve.IsOnCurve(x0, y0))
|
||||
|
||||
x2, y2 := curve.Add(x1, y1, x0, y0)
|
||||
fmt.Printf("Output is Point(%x, %x)\n", x2, y2)
|
||||
|
||||
if (x1.Cmp(x2) == 0) && (y1.Cmp(y2) == 0) {
|
||||
// fmt.Printf("Correct, Point on curve is the same after Zero addition\n")
|
||||
} else {
|
||||
t.Error("Incorrect, Point on curve changed after Zero addition\n")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOnCurveVerify(t *testing.T) {
|
||||
numRing := 5
|
||||
ringSize := 10
|
||||
s := 5
|
||||
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||
ringSignature, err := Sign(m, rings, privkeys, s)
|
||||
if err != nil {
|
||||
t.Error("Failed to create Ring signature")
|
||||
}
|
||||
|
||||
valid := Verify(ringSignature, false)
|
||||
if !valid {
|
||||
t.Error("Incorrect, unmodified ringSignature should be valid")
|
||||
}
|
||||
|
||||
ringsModified := ringSignature.Ring
|
||||
ringsModified[0][0].X = big.NewInt(1)
|
||||
ringsModified[0][0].Y = big.NewInt(1)
|
||||
valid = Verify(ringSignature, false)
|
||||
if valid {
|
||||
t.Error("Incorrect, modified ringSignature should be invalid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOnCurveDeserialize(t *testing.T) {
|
||||
numRing := 5
|
||||
ringSize := 10
|
||||
s := 5
|
||||
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||
ringSignature, err := Sign(m, rings, privkeys, s)
|
||||
if err != nil {
|
||||
t.Error("Failed to create Ring signature")
|
||||
}
|
||||
|
||||
sig, err := ringSignature.Serialize()
|
||||
if err != nil {
|
||||
t.Error("Failed to Serialize input Ring signature")
|
||||
}
|
||||
_, err = Deserialize(sig)
|
||||
if err != nil {
|
||||
t.Error("Failed to Deserialize")
|
||||
}
|
||||
|
||||
ringsModified := ringSignature.Ring
|
||||
ringsModified[0][0].X = big.NewInt(1)
|
||||
ringsModified[0][0].Y = big.NewInt(1)
|
||||
|
||||
sig, err = ringSignature.Serialize()
|
||||
if err != nil {
|
||||
t.Error("Failed to Serialize input Ring signature")
|
||||
}
|
||||
_, err = Deserialize(sig)
|
||||
assert.EqualError(t, err, "failed to deserialize, invalid ring signature")
|
||||
}
|
||||
|
||||
func TestCurveScalarMult(t *testing.T) {
|
||||
curve := crypto.S256().(*secp256k1.BitCurve)
|
||||
|
||||
x, y := curve.ScalarBaseMult(curve.Params().N.Bytes())
|
||||
if x == nil && y == nil {
|
||||
fmt.Println("Scalar multiplication with base point returns nil when scalar is the scalar field")
|
||||
}
|
||||
|
||||
x2, y2 := curve.ScalarMult(new(big.Int).SetUint64(uint64(100)), new(big.Int).SetUint64(uint64(2)), curve.Params().N.Bytes())
|
||||
if x2 == nil && y2 == nil {
|
||||
fmt.Println("Scalar multiplication with a point (not necessarily on curve) returns nil when scalar is the scalar field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNilPointerDereferencePanic(t *testing.T) {
|
||||
numRing := 5
|
||||
ringSize := 10
|
||||
s := 7
|
||||
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||
|
||||
ringSig, err := Sign(m, rings, privkeys, s)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set up")
|
||||
}
|
||||
|
||||
ringSig.S[0][0] = curve.Params().N // change one sig to the scalar field
|
||||
|
||||
sig, err := ringSig.Serialize()
|
||||
if err != nil {
|
||||
t.Error("Failed to Serialize input Ring signature")
|
||||
}
|
||||
|
||||
_ , err = Deserialize(sig)
|
||||
// Should failed to verify Ring signature as the signature is invalid
|
||||
assert.EqualError(t, err, "failed to deserialize, invalid ring signature")
|
||||
}
|
||||
Loading…
Reference in a new issue