Compare commits

...

6 Commits

Author SHA1 Message Date
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
arnaucube
71dbddb5f1 Abstract & expose CompressedPointToSignAndY 2020-12-21 16:12:49 +01:00
Eduard S
0a5c6acba3 Merge pull request #33 from iden3/feature/pkcomp-scanvalue
Add scanner/valuer interface to babyjub.PublicKeyComp
2020-12-21 10:31:37 +01:00
arnaucube
a366175021 Add scanner/valuer interface to babyjub.PublicKeyComp 2020-12-18 20:44:29 +01:00
Eduard S
a2015adb2f Merge pull request #32 from iden3/feature/upgrade-linters
Upgrade linters
2020-12-18 12:11:45 +01:00
4 changed files with 80 additions and 12 deletions

View File

@@ -203,31 +203,46 @@ func PointCoordSign(c *big.Int) bool {
return c.Cmp(new(big.Int).Rsh(constants.Q, 1)) == 1
}
// PackPoint packs a point into a 32 byte array
func PackPoint(ay *big.Int, sign bool) [32]byte {
leBuf := utils.BigIntLEBytes(ay)
// PackSignY packs the given sign and the coordinate Y of a point into a 32
// byte array. This method does not check that the values belong to a valid
// Point in the curve.
func PackSignY(sign bool, y *big.Int) [32]byte {
leBuf := utils.BigIntLEBytes(y)
if sign {
leBuf[31] = leBuf[31] | 0x80 //nolint:gomnd
}
return leBuf
}
// UnpackSignY 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 UnpackSignY(leBuf [32]byte) (bool, *big.Int) {
sign := false
y := big.NewInt(0)
if (leBuf[31] & 0x80) != 0x00 { //nolint:gomnd
sign = true
leBuf[31] = leBuf[31] & 0x7F //nolint:gomnd
}
utils.SetBigIntFromLEBytes(y, leBuf[:])
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 PackPoint(p.Y, sign)
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) {
sign := false
if (leBuf[31] & 0x80) != 0x00 { //nolint:gomnd
sign = true
leBuf[31] = leBuf[31] & 0x7F //nolint:gomnd
}
utils.SetBigIntFromLEBytes(p.Y, leBuf[:])
var sign bool
sign, p.Y = UnpackSignY(leBuf)
return PointFromSignAndY(sign, p.Y)
}

View File

@@ -218,6 +218,26 @@ func TestPointFromSignAndy(t *testing.T) {
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) {
x := utils.NewIntFromString(
"17777552123799933955779906779655732241715742912184938656739573121738514868268")

View File

@@ -354,3 +354,21 @@ func (pk PublicKey) Value() (driver.Value, error) {
comp := pk.Compress()
return comp[:], nil
}
// Scan implements Scanner for database/sql.
func (pkComp *PublicKeyComp) Scan(src interface{}) error {
srcB, ok := src.([]byte)
if !ok {
return fmt.Errorf("can't scan %T into PublicKeyComp", src)
}
if len(srcB) != 32 {
return fmt.Errorf("can't scan []byte of len %d into PublicKeyComp, want %d", len(srcB), 32)
}
copy(pkComp[:], srcB)
return nil
}
// Value implements valuer for database/sql.
func (pkComp PublicKeyComp) Value() (driver.Value, error) {
return pkComp[:], nil
}

View File

@@ -139,7 +139,7 @@ func TestCompressDecompress(t *testing.T) {
func TestSignatureCompScannerValuer(t *testing.T) {
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()
scan := privK.SignPoseidon(big.NewInt(1)).Compress()
fromDB, err := value.Value()
@@ -160,7 +160,7 @@ func TestSignatureScannerValuer(t *testing.T) {
assert.Equal(t, value, scan)
}
func TestPubKeyScannerValuer(t *testing.T) {
func TestPublicKeyScannerValuer(t *testing.T) {
privKValue := NewRandPrivKey()
pubKValue := privKValue.Public()
privKScan := NewRandPrivKey()
@@ -175,6 +175,21 @@ func TestPubKeyScannerValuer(t *testing.T) {
assert.Equal(t, value, scan)
}
func TestPublicKeyCompScannerValuer(t *testing.T) {
privKValue := NewRandPrivKey()
pubKCompValue := privKValue.Public().Compress()
privKScan := NewRandPrivKey()
pubKCompScan := privKScan.Public().Compress()
var value driver.Valuer
var scan sql.Scanner
value = &pubKCompValue
scan = &pubKCompScan
fromDB, err := value.Value()
assert.Nil(t, err)
assert.Nil(t, scan.Scan(fromDB))
assert.Equal(t, value, scan)
}
func BenchmarkBabyjubEddsa(b *testing.B) {
var k PrivateKey
_, err := hex.Decode(k[:],