mirror of
https://github.com/arnaucube/go-iden3-crypto.git
synced 2026-02-07 11:36:41 +01:00
Compare commits
3 Commits
c1
...
feature/po
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
833f68a614 | ||
|
|
29a66457f0 | ||
|
|
f22be3cdee |
@@ -181,6 +181,14 @@ func (p *Point) Decompress(leBuf [32]byte) (*Point, error) {
|
|||||||
leBuf[31] = leBuf[31] & 0x7F
|
leBuf[31] = leBuf[31] & 0x7F
|
||||||
}
|
}
|
||||||
utils.SetBigIntFromLEBytes(p.Y, leBuf[:])
|
utils.SetBigIntFromLEBytes(p.Y, leBuf[:])
|
||||||
|
return PointFromSignAndY(sign, p.Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PointFromSignAndY returns a Point from a Sign and the Y coordinate
|
||||||
|
func PointFromSignAndY(sign bool, y *big.Int) (*Point, error) {
|
||||||
|
var p Point
|
||||||
|
p.X = big.NewInt(0)
|
||||||
|
p.Y = y
|
||||||
if p.Y.Cmp(constants.Q) >= 0 {
|
if p.Y.Cmp(constants.Q) >= 0 {
|
||||||
return nil, fmt.Errorf("p.y >= Q")
|
return nil, fmt.Errorf("p.y >= Q")
|
||||||
}
|
}
|
||||||
@@ -209,5 +217,5 @@ func (p *Point) Decompress(leBuf [32]byte) (*Point, error) {
|
|||||||
}
|
}
|
||||||
p.X.Mod(p.X, constants.Q)
|
p.X.Mod(p.X, constants.Q)
|
||||||
|
|
||||||
return p, nil
|
return &p, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,6 +192,20 @@ func TestInSubGroup2(t *testing.T) {
|
|||||||
assert.Equal(t, true, p.InSubGroup())
|
assert.Equal(t, true, p.InSubGroup())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPointFromSignAndy(t *testing.T) {
|
||||||
|
x := utils.NewIntFromString(
|
||||||
|
"17777552123799933955779906779655732241715742912184938656739573121738514868268")
|
||||||
|
y := utils.NewIntFromString(
|
||||||
|
"2626589144620713026669568689430873010625803728049924121243784502389097019475")
|
||||||
|
p := &Point{X: x, Y: y}
|
||||||
|
|
||||||
|
sign := PointCoordSign(p.X)
|
||||||
|
p2, err := PointFromSignAndY(sign, p.Y)
|
||||||
|
assert.Equal(t, nil, err)
|
||||||
|
assert.Equal(t, p.X.String(), p2.X.String())
|
||||||
|
assert.Equal(t, p.Y.String(), p2.Y.String())
|
||||||
|
}
|
||||||
|
|
||||||
func TestCompressDecompress1(t *testing.T) {
|
func TestCompressDecompress1(t *testing.T) {
|
||||||
x := utils.NewIntFromString(
|
x := utils.NewIntFromString(
|
||||||
"17777552123799933955779906779655732241715742912184938656739573121738514868268")
|
"17777552123799933955779906779655732241715742912184938656739573121738514868268")
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ func (k *PrivateKey) SignPoseidon(msg *big.Int) *Signature {
|
|||||||
A := k.Public().Point()
|
A := k.Public().Point()
|
||||||
|
|
||||||
hmInput := [poseidon.T]*big.Int{R8.X, R8.Y, A.X, A.Y, msg, big.NewInt(int64(0))}
|
hmInput := [poseidon.T]*big.Int{R8.X, R8.Y, A.X, A.Y, msg, big.NewInt(int64(0))}
|
||||||
hm, err := poseidon.PoseidonHash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
|
hm, err := poseidon.Hash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -248,7 +248,7 @@ func (k *PrivateKey) SignPoseidon(msg *big.Int) *Signature {
|
|||||||
// using blake-512 hash for buffer hashing and Poseidon for big.Int hashing.
|
// using blake-512 hash for buffer hashing and Poseidon for big.Int hashing.
|
||||||
func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool {
|
func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool {
|
||||||
hmInput := [poseidon.T]*big.Int{sig.R8.X, sig.R8.Y, p.X, p.Y, msg, big.NewInt(int64(0))}
|
hmInput := [poseidon.T]*big.Int{sig.R8.X, sig.R8.Y, p.X, p.Y, msg, big.NewInt(int64(0))}
|
||||||
hm, err := poseidon.PoseidonHash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
|
hm, err := poseidon.Hash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,8 +120,8 @@ func mix(state [T]*ff.Element, newState [T]*ff.Element, m [T][T]*ff.Element) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PoseidonHash computes the Poseidon hash for the given inputs
|
// Hash computes the Poseidon hash for the given inputs
|
||||||
func PoseidonHash(inpBI [T]*big.Int) (*big.Int, error) {
|
func Hash(inpBI [T]*big.Int) (*big.Int, error) {
|
||||||
if !utils.CheckBigIntArrayInField(inpBI[:]) {
|
if !utils.CheckBigIntArrayInField(inpBI[:]) {
|
||||||
return nil, errors.New("inputs values not inside Finite Field")
|
return nil, errors.New("inputs values not inside Finite Field")
|
||||||
}
|
}
|
||||||
@@ -148,9 +148,9 @@ func PoseidonHash(inpBI [T]*big.Int) (*big.Int, error) {
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash performs the Poseidon hash over a ff.Element array
|
// HashSlice performs the Poseidon hash over a ff.Element array
|
||||||
// in chunks of 5 elements
|
// in chunks of 5 elements
|
||||||
func Hash(arr []*big.Int) (*big.Int, error) {
|
func HashSlice(arr []*big.Int) (*big.Int, error) {
|
||||||
r := big.NewInt(int64(1))
|
r := big.NewInt(int64(1))
|
||||||
for i := 0; i < len(arr); i = i + T - 1 {
|
for i := 0; i < len(arr); i = i + T - 1 {
|
||||||
var toHash [T]*big.Int
|
var toHash [T]*big.Int
|
||||||
@@ -167,7 +167,7 @@ func Hash(arr []*big.Int) (*big.Int, error) {
|
|||||||
toHash[j] = big.NewInt(0)
|
toHash[j] = big.NewInt(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
ph, err := PoseidonHash(toHash)
|
ph, err := Hash(toHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -176,26 +176,3 @@ func Hash(arr []*big.Int) (*big.Int, error) {
|
|||||||
|
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HashBytes hashes a msg byte slice by blocks of 31 bytes encoded as
|
|
||||||
// little-endian
|
|
||||||
func HashBytes(b []byte) *big.Int {
|
|
||||||
n := 31
|
|
||||||
bElems := make([]*big.Int, 0, len(b)/n+1)
|
|
||||||
for i := 0; i < len(b)/n; i++ {
|
|
||||||
v := big.NewInt(int64(0))
|
|
||||||
utils.SetBigIntFromLEBytes(v, b[n*i:n*(i+1)])
|
|
||||||
bElems = append(bElems, v)
|
|
||||||
|
|
||||||
}
|
|
||||||
if len(b)%n != 0 {
|
|
||||||
v := big.NewInt(int64(0))
|
|
||||||
utils.SetBigIntFromLEBytes(v, b[(len(b)/n)*n:])
|
|
||||||
bElems = append(bElems, v)
|
|
||||||
}
|
|
||||||
h, err := Hash(bElems)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,16 +15,31 @@ func TestBlake2bVersion(t *testing.T) {
|
|||||||
assert.Equal(t, "e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1", hex.EncodeToString(h[:]))
|
assert.Equal(t, "e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1", hex.EncodeToString(h[:]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPoseidon(t *testing.T) {
|
func TestPoseidonHash(t *testing.T) {
|
||||||
|
b0 := big.NewInt(0)
|
||||||
b1 := big.NewInt(1)
|
b1 := big.NewInt(1)
|
||||||
b2 := big.NewInt(2)
|
b2 := big.NewInt(2)
|
||||||
h, err := Hash([]*big.Int{b1, b2})
|
h, err := Hash([T]*big.Int{b1, b2, b0, b0, b0, b0})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "12242166908188651009877250812424843524687801523336557272219921456462821518061", h.String())
|
||||||
|
|
||||||
|
b3 := big.NewInt(3)
|
||||||
|
b4 := big.NewInt(4)
|
||||||
|
h, err = Hash([T]*big.Int{b3, b4, b0, b0, b0, b0})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "17185195740979599334254027721507328033796809509313949281114643312710535000993", h.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPoseidonHashArbitraryLen(t *testing.T) {
|
||||||
|
b1 := big.NewInt(1)
|
||||||
|
b2 := big.NewInt(2)
|
||||||
|
h, err := HashSlice([]*big.Int{b1, b2})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "4932297968297298434239270129193057052722409868268166443802652458940273154855", h.String())
|
assert.Equal(t, "4932297968297298434239270129193057052722409868268166443802652458940273154855", h.String())
|
||||||
|
|
||||||
b3 := big.NewInt(3)
|
b3 := big.NewInt(3)
|
||||||
b4 := big.NewInt(4)
|
b4 := big.NewInt(4)
|
||||||
h, err = Hash([]*big.Int{b3, b4})
|
h, err = HashSlice([]*big.Int{b3, b4})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "4635491972858758537477743930622086396911540895966845494943021655521913507504", h.String())
|
assert.Equal(t, "4635491972858758537477743930622086396911540895966845494943021655521913507504", h.String())
|
||||||
|
|
||||||
@@ -36,7 +51,7 @@ func TestPoseidon(t *testing.T) {
|
|||||||
b10 := big.NewInt(10)
|
b10 := big.NewInt(10)
|
||||||
b11 := big.NewInt(11)
|
b11 := big.NewInt(11)
|
||||||
b12 := big.NewInt(12)
|
b12 := big.NewInt(12)
|
||||||
h, err = Hash([]*big.Int{b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12})
|
h, err = HashSlice([]*big.Int{b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "15278801138972282646981503374384603641625274360649669926363020545395022098027", h.String())
|
assert.Equal(t, "15278801138972282646981503374384603641625274360649669926363020545395022098027", h.String())
|
||||||
|
|
||||||
@@ -53,7 +68,7 @@ func TestPoseidon(t *testing.T) {
|
|||||||
utils.SetBigIntFromLEBytes(v, msg[(len(msg)/n)*n:])
|
utils.SetBigIntFromLEBytes(v, msg[(len(msg)/n)*n:])
|
||||||
msgElems = append(msgElems, v)
|
msgElems = append(msgElems, v)
|
||||||
}
|
}
|
||||||
hmsg, err := Hash(msgElems)
|
hmsg, err := HashSlice(msgElems)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "16019700159595764790637132363672701294192939959594423814006267756172551741065", hmsg.String())
|
assert.Equal(t, "16019700159595764790637132363672701294192939959594423814006267756172551741065", hmsg.String())
|
||||||
|
|
||||||
@@ -69,33 +84,30 @@ func TestPoseidon(t *testing.T) {
|
|||||||
utils.SetBigIntFromLEBytes(v, msg2[(len(msg2)/n)*n:])
|
utils.SetBigIntFromLEBytes(v, msg2[(len(msg2)/n)*n:])
|
||||||
msg2Elems = append(msg2Elems, v)
|
msg2Elems = append(msg2Elems, v)
|
||||||
}
|
}
|
||||||
hmsg2, err := Hash(msg2Elems)
|
hmsg2, err := HashSlice(msg2Elems)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "2978613163687734485261639854325792381691890647104372645321246092227111432722", hmsg2.String())
|
assert.Equal(t, "2978613163687734485261639854325792381691890647104372645321246092227111432722", hmsg2.String())
|
||||||
|
|
||||||
hmsg2 = HashBytes(msg2)
|
|
||||||
assert.Equal(t, "2978613163687734485261639854325792381691890647104372645321246092227111432722", hmsg2.String())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPoseidonBrokenChunks(t *testing.T) {
|
func TestPoseidonHashArbitraryLenBrokenChunks(t *testing.T) {
|
||||||
h1, err := Hash([]*big.Int{big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4),
|
h1, err := HashSlice([]*big.Int{big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4),
|
||||||
big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9)})
|
big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9)})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
h2, err := Hash([]*big.Int{big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9),
|
h2, err := HashSlice([]*big.Int{big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9),
|
||||||
big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4)})
|
big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4)})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.NotEqual(t, h1, h2)
|
assert.NotEqual(t, h1, h2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPoseidonBrokenPadding(t *testing.T) {
|
func TestPoseidonHashArbitraryLenBrokenPadding(t *testing.T) {
|
||||||
h1, err := Hash([]*big.Int{big.NewInt(int64(1))})
|
h1, err := HashSlice([]*big.Int{big.NewInt(int64(1))})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
h2, err := Hash([]*big.Int{big.NewInt(int64(1)), big.NewInt(int64(0))})
|
h2, err := HashSlice([]*big.Int{big.NewInt(int64(1)), big.NewInt(int64(0))})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.NotEqual(t, h1, h2)
|
assert.NotEqual(t, h1, h2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPoseidon(b *testing.B) {
|
func BenchmarkPoseidonHashSmallValues(b *testing.B) {
|
||||||
b12 := big.NewInt(int64(12))
|
b12 := big.NewInt(int64(12))
|
||||||
b45 := big.NewInt(int64(45))
|
b45 := big.NewInt(int64(45))
|
||||||
b78 := big.NewInt(int64(78))
|
b78 := big.NewInt(int64(78))
|
||||||
@@ -103,17 +115,16 @@ func BenchmarkPoseidon(b *testing.B) {
|
|||||||
bigArray4 := []*big.Int{b12, b45, b78, b41}
|
bigArray4 := []*big.Int{b12, b45, b78, b41}
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Hash(bigArray4) //nolint:errcheck
|
HashSlice(bigArray4) //nolint:errcheck
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPoseidonLarge(b *testing.B) {
|
func BenchmarkPoseidonHash(b *testing.B) {
|
||||||
b12 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733")
|
b0 := big.NewInt(0)
|
||||||
b45 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733")
|
b1 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061")
|
||||||
b78 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733")
|
b2 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061")
|
||||||
b41 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733")
|
|
||||||
|
|
||||||
bigArray4 := []*big.Int{b12, b45, b78, b41}
|
bigArray4 := [T]*big.Int{b1, b2, b0, b0, b0, b0}
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
Hash(bigArray4) //nolint:errcheck
|
Hash(bigArray4) //nolint:errcheck
|
||||||
|
|||||||
Reference in New Issue
Block a user