Compare commits

..

4 Commits

Author SHA1 Message Date
arnaucube
590573a0af Update Poseidon last changes of the reference impl
Update Poseidon to last changes of the reference implementation from
26ddaa91db

Compatible with update at circomlib
(cf853c1cc9)
2021-03-08 14:59:42 +01:00
Eduard S
58e589b6eb Merge pull request #35 from iden3/feature/comp-point-test
Update and add test for PackSignY & UnpackSignY
2020-12-21 17:03:44 +01:00
arnaucube
2318fd7044 Update and add test for PackSignY & UnpackSignY
- Update PackSignY & UnpackSignY interface and description
- Add test for UnpackSignY & PackPoint
2020-12-21 16:58:13 +01:00
Eduard S
a0722b9e8f Merge pull request #34 from iden3/feature/exp-comppoint-signy
Abstract & expose CompressedPointToSignAndY
2020-12-21 16:21:27 +01:00
5 changed files with 62 additions and 42 deletions

View File

@@ -203,37 +203,24 @@ func PointCoordSign(c *big.Int) bool {
return c.Cmp(new(big.Int).Rsh(constants.Q, 1)) == 1 return c.Cmp(new(big.Int).Rsh(constants.Q, 1)) == 1
} }
// PackPoint packs a point into a 32 byte array // PackSignY packs the given sign and the coordinate Y of a point into a 32
func PackPoint(ay *big.Int, sign bool) [32]byte { // byte array. This method does not check that the values belong to a valid
leBuf := utils.BigIntLEBytes(ay) // Point in the curve.
func PackSignY(sign bool, y *big.Int) [32]byte {
leBuf := utils.BigIntLEBytes(y)
if sign { if sign {
leBuf[31] = leBuf[31] | 0x80 //nolint:gomnd leBuf[31] = leBuf[31] | 0x80 //nolint:gomnd
} }
return leBuf return leBuf
} }
// Compress the point into a 32 byte array that contains the y coordinate in // UnpackSignY returns the sign and coordinate Y from a given compressed point.
// little endian and the sign of the x coordinate. // This method does not check that the Point belongs to the BabyJubJub curve,
func (p *Point) Compress() [32]byte { // thus does not return error in such case. This method is intended to obtain
sign := PointCoordSign(p.X) // the sign and the Y coordinate without checking if the point belongs to the
return PackPoint(p.Y, sign) // curve, if the objective is to uncompress a point, Decompress method should
} // be used instead.
func UnpackSignY(leBuf [32]byte) (bool, *big.Int) {
// Decompress a compressed Point into p, and also returns the decompressed
// Point. Returns error if the compressed Point is invalid.
func (p *Point) Decompress(leBuf [32]byte) (*Point, error) {
var sign bool
sign, p.Y = CompressedPointToSignAndY(leBuf)
return PointFromSignAndY(sign, p.Y)
}
// CompressedPointToSignAndY returns the sign and coordinate Y from a given
// compressed point. This method does not check that the Point belongs to the
// BabyJubJub curve, thus does not return error in such case. This method is
// intended to obtain the sign and the Y coordinate without checking if the
// point belongs to the curve, if the objective is to uncompress a point
// Decompress method should be used instead.
func CompressedPointToSignAndY(leBuf [32]byte) (bool, *big.Int) {
sign := false sign := false
y := big.NewInt(0) y := big.NewInt(0)
if (leBuf[31] & 0x80) != 0x00 { //nolint:gomnd if (leBuf[31] & 0x80) != 0x00 { //nolint:gomnd
@@ -244,6 +231,21 @@ func CompressedPointToSignAndY(leBuf [32]byte) (bool, *big.Int) {
return sign, y return sign, y
} }
// Compress the point into a 32 byte array that contains the y coordinate in
// little endian and the sign of the x coordinate.
func (p *Point) Compress() [32]byte {
sign := PointCoordSign(p.X)
return PackSignY(sign, p.Y)
}
// Decompress a compressed Point into p, and also returns the decompressed
// Point. Returns error if the compressed Point is invalid.
func (p *Point) Decompress(leBuf [32]byte) (*Point, error) {
var sign bool
sign, p.Y = UnpackSignY(leBuf)
return PointFromSignAndY(sign, p.Y)
}
// PointFromSignAndY returns a Point from a Sign and the Y coordinate // PointFromSignAndY returns a Point from a Sign and the Y coordinate
func PointFromSignAndY(sign bool, y *big.Int) (*Point, error) { func PointFromSignAndY(sign bool, y *big.Int) (*Point, error) {
var p Point var p Point

View File

@@ -218,6 +218,26 @@ func TestPointFromSignAndy(t *testing.T) {
assert.Equal(t, p.Y.String(), p2.Y.String()) assert.Equal(t, p.Y.String(), p2.Y.String())
} }
func TestPackAndUnpackSignY(t *testing.T) {
x := utils.NewIntFromString(
"17777552123799933955779906779655732241715742912184938656739573121738514868268")
y := utils.NewIntFromString(
"2626589144620713026669568689430873010625803728049924121243784502389097019475")
p := &Point{X: x, Y: y}
pComp := p.Compress()
s, y := UnpackSignY(pComp)
pComp2 := PackSignY(s, y)
assert.Equal(t, pComp, pComp2)
emptyPointComp := [32]byte{}
s, y = UnpackSignY(emptyPointComp)
pComp2 = PackSignY(s, y)
assert.Equal(t, emptyPointComp, pComp2)
}
func TestCompressDecompress1(t *testing.T) { func TestCompressDecompress1(t *testing.T) {
x := utils.NewIntFromString( x := utils.NewIntFromString(
"17777552123799933955779906779655732241715742912184938656739573121738514868268") "17777552123799933955779906779655732241715742912184938656739573121738514868268")

View File

@@ -97,7 +97,7 @@ func TestSignVerifyPoseidon(t *testing.T) {
"15383486972088797283337779941324724402501462225528836549661220478783371668959", "15383486972088797283337779941324724402501462225528836549661220478783371668959",
sig.R8.Y.String()) sig.R8.Y.String())
assert.Equal(t, assert.Equal(t,
"1398758333392199195742243841591064350253744445503462896781493968760929513778", "1672775540645840396591609181675628451599263765380031905495115170613215233181",
sig.S.String()) sig.S.String())
ok := pk.VerifyPoseidon(msg, sig) ok := pk.VerifyPoseidon(msg, sig)
@@ -109,7 +109,7 @@ func TestSignVerifyPoseidon(t *testing.T) {
assert.Equal(t, ""+ assert.Equal(t, ""+
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+ "dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
"32f16b0f2f4c4e1169aa59685637e1429b6581a9531d058d65f4ab224eab1703", "9d043ece562a8f82bfc0adb640c0107a7d3a27c1c7c1a6179a0da73de5c1b203",
hex.EncodeToString(sigBuf[:])) hex.EncodeToString(sigBuf[:]))
ok = pk.VerifyPoseidon(msg, sig2) ok = pk.VerifyPoseidon(msg, sig2)
@@ -139,7 +139,7 @@ func TestCompressDecompress(t *testing.T) {
func TestSignatureCompScannerValuer(t *testing.T) { func TestSignatureCompScannerValuer(t *testing.T) {
privK := NewRandPrivKey() privK := NewRandPrivKey()
var value driver.Valuer //nolint:gosimple this is done to ensure interface compability var value driver.Valuer //nolint:gosimple this is done to ensure interface compatibility
value = privK.SignPoseidon(big.NewInt(674238462)).Compress() value = privK.SignPoseidon(big.NewInt(674238462)).Compress()
scan := privK.SignPoseidon(big.NewInt(1)).Compress() scan := privK.SignPoseidon(big.NewInt(1)).Compress()
fromDB, err := value.Value() fromDB, err := value.Value()

View File

@@ -47,7 +47,7 @@ func mix(state []*ff.Element, newState []*ff.Element, m [][]*ff.Element) {
for i := 0; i < len(state); i++ { for i := 0; i < len(state); i++ {
newState[i].SetUint64(0) newState[i].SetUint64(0)
for j := 0; j < len(state); j++ { for j := 0; j < len(state); j++ {
mul.Mul(m[j][i], state[j]) mul.Mul(m[i][j], state[j])
newState[i].Add(newState[i], mul) newState[i].Add(newState[i], mul)
} }
} }
@@ -64,8 +64,8 @@ func Hash(inpBI []*big.Int) (*big.Int, error) {
} }
inp := utils.BigIntArrayToElementArray(inpBI[:]) inp := utils.BigIntArrayToElementArray(inpBI[:])
state := make([]*ff.Element, t) state := make([]*ff.Element, t)
copy(state[:], inp[:]) state[0] = zero()
state[len(state)-1] = zero() copy(state[1:], inp[:])
nRoundsF := NROUNDSF nRoundsF := NROUNDSF
nRoundsP := NROUNDSP[t-2] nRoundsP := NROUNDSP[t-2]
@@ -79,11 +79,9 @@ func Hash(inpBI []*big.Int) (*big.Int, error) {
for i := 0; i < nRoundsF+nRoundsP; i++ { for i := 0; i < nRoundsF+nRoundsP; i++ {
ark(state, c.c[t-2], i*t) ark(state, c.c[t-2], i*t)
sbox(nRoundsF, nRoundsP, state, i) sbox(nRoundsF, nRoundsP, state, i)
if i < nRoundsF+nRoundsP-1 {
mix(state, newState, c.m[t-2]) mix(state, newState, c.m[t-2])
state, newState = newState, state state, newState = newState, state
} }
}
rE := state[0] rE := state[0]
r := big.NewInt(0) r := big.NewInt(0)
rE.ToBigIntRegular(r) rE.ToBigIntRegular(r)

View File

@@ -25,24 +25,24 @@ func TestPoseidonHash(t *testing.T) {
h, err := Hash([]*big.Int{b1}) h, err := Hash([]*big.Int{b1})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, assert.Equal(t,
"11043376183861534927536506085090418075369306574649619885724436265926427398571", "18586133768512220936620570745912940619677854269274689475585506675881198879027",
h.String()) h.String())
h, err = Hash([]*big.Int{b1, b2}) h, err = Hash([]*big.Int{b1, b2})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, assert.Equal(t,
"17117985411748610629288516079940078114952304104811071254131751175361957805920", "7853200120776062878684798364095072458815029376092732009249414926327459813530",
h.String()) h.String())
h, err = Hash([]*big.Int{b1, b2, b0, b0, b0}) h, err = Hash([]*big.Int{b1, b2, b0, b0, b0})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, assert.Equal(t,
"3975478831357328722254985704342968745327876719981393787143845259590563829094", "1018317224307729531995786483840663576608797660851238720571059489595066344487",
h.String()) h.String())
h, err = Hash([]*big.Int{b1, b2, b0, b0, b0, b0}) h, err = Hash([]*big.Int{b1, b2, b0, b0, b0, b0})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, assert.Equal(t,
"19772360636270345724087386688434825760738403416279047262510528378903625000110", "15336558801450556532856248569924170992202208561737609669134139141992924267169",
h.String()) h.String())
b3 := big.NewInt(3) b3 := big.NewInt(3)
@@ -50,12 +50,12 @@ func TestPoseidonHash(t *testing.T) {
h, err = Hash([]*big.Int{b3, b4, b0, b0, b0}) h, err = Hash([]*big.Int{b3, b4, b0, b0, b0})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, assert.Equal(t,
"3181200837746671699652342497997860344148947482942465819251904554707352676086", "5811595552068139067952687508729883632420015185677766880877743348592482390548",
h.String()) h.String())
h, err = Hash([]*big.Int{b3, b4, b0, b0, b0, b0}) h, err = Hash([]*big.Int{b3, b4, b0, b0, b0, b0})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, assert.Equal(t,
"8386348873272147968934270337233829407378789978142456170950021426339096575008", "12263118664590987767234828103155242843640892839966517009184493198782366909018",
h.String()) h.String())
b5 := big.NewInt(5) b5 := big.NewInt(5)
@@ -63,7 +63,7 @@ func TestPoseidonHash(t *testing.T) {
h, err = Hash([]*big.Int{b1, b2, b3, b4, b5, b6}) h, err = Hash([]*big.Int{b1, b2, b3, b4, b5, b6})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, assert.Equal(t,
"5202465217520500374834597824465244016759843635092906214933648999760272616044", "20400040500897583745843009878988256314335038853985262692600694741116813247201",
h.String()) h.String())
} }