Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add curve type, slip10 type, and pubKey compression #297

Merged
merged 6 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ run:
deadline: 10m
linters:
enable:
- vet
- govet
- gofmt
- misspell
- goconst
Expand Down
3 changes: 3 additions & 0 deletions crypto/binaryquadraticform/binaryquadratic.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,10 +604,13 @@ func partialGCD(R2, R1, C2, C1, bound *big.Int) (*big.Int, *big.Int, *big.Int, *
if T < 0 {
T = 0
}
// #nosec: G115: integer overflow conversion int -> uint32
r = new(big.Int).Rsh(R2, uint(T))
rr2 = r.Int64()
// #nosec: G115: integer overflow conversion int -> uint32
r = new(big.Int).Rsh(R1, uint(T))
rr1 = r.Int64()
// #nosec: G115: integer overflow conversion int -> uint32
r = new(big.Int).Rsh(bound, uint(T))
bb = r.Int64()

Expand Down
2 changes: 1 addition & 1 deletion crypto/binaryquadraticform/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"math/big"
)

//go:generate mockery -name Exper
//go:generate mockery --name Exper
type Exper interface {
Exp(power *big.Int) (*BQuadraticForm, error)
ToMessage() *BQForm
Expand Down
72 changes: 72 additions & 0 deletions crypto/binaryquadraticform/mocks/Exper.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crypto/bip32/child/0_initial_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ func newChildKeyFunc(startIndex int, garbleStart int, garbleEnd int, parseResult

shareBits := make([]uint8, 512)
for i := 0; i < len(shareBits); i++ {
// #nosec: G115: integer overflow conversion int -> uint32
shareBits[i] = uint8(sm.share.Bit(i))
}
garcir, garMsg, err := cir.Garbled(bip32.Kappa, shareBits, circuit.EncryptFunc(startIndex))
Expand Down Expand Up @@ -289,11 +290,13 @@ func getMessage(msg types.Message) *Message {
func computePaddingInput(childIndex uint32, firstState []uint64) ([]uint8, error) {
otherInfo := make([]uint8, 512)
for i := 0; i < 512; i++ {
// #nosec: G115: integer overflow conversion int -> uint32
otherInfo[i] = uint8(secp256k1N.Bit(i))
}
indexKey := make([]uint8, 32)
bigIndexKey := new(big.Int).SetUint64(uint64(childIndex))
for i := 0; i < 32; i++ {
// #nosec: G115: integer overflow conversion int -> uint32
indexKey[31-i] = uint8(bigIndexKey.Bit(i))
}
zeroShaPadding := make([]uint8, 717)
Expand Down
3 changes: 3 additions & 0 deletions crypto/bip32/child/share_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func NewShareManager(share *big.Int, pubKey *ecpointgrouplaw.ECPoint, chainCode
i++
}
}
// #nosec: G115: integer overflow conversion int -> uint32
cos, err := bbks.ComputeBkCoefficient(uint32(len(bks)), n)
if err != nil {
return nil, err
Expand Down Expand Up @@ -137,6 +138,7 @@ func (sHolder *shareManager) ComputeHardenedChildShare(childIndex uint32, second
if childPubKey.IsIdentity() {
return nil, ErrIdentityChildPublicKey
}
// #nosec: G115: integer overflow conversion int -> uint32
cos, err := sHolder.bks.ComputeBkCoefficient(uint32(len(sHolder.bks)), curveN)
if err != nil {
return nil, err
Expand Down Expand Up @@ -186,6 +188,7 @@ func (sHolder *shareManager) ComputeNonHardenedChildShare(childIndex uint32) (*c
}

// TODO: need to define how to add translate in each party
// #nosec: G115: integer overflow conversion int -> uint32
cos, err := sHolder.bks.ComputeBkCoefficient(uint32(len(sHolder.bks)), curveN)
if err != nil {
return nil, err
Expand Down
4 changes: 4 additions & 0 deletions crypto/birkhoffinterpolation/birkhoffinterpolation.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ func (p *BkParameter) String() string {

func (p *BkParameter) GetLinearEquationCoefficient(fieldOrder *big.Int, degreePoly uint32) []*big.Int {
result := make([]*big.Int, degreePoly+1)
// #nosec: G115: integer overflow conversion int -> uint32
for i := uint32(0); i < uint32(len(result)); i++ {
result[i] = p.getDiffMonomialCoeff(fieldOrder, i)
}
Expand Down Expand Up @@ -178,6 +179,7 @@ func (bks BkParameters) ensureRankAndOrder(threshold uint32, fieldOrder *big.Int
if err := utils.EnsureFieldOrder(fieldOrder); err != nil {
return err
}
// #nosec: G115: integer overflow conversion int -> uint32
if uint32(bks.Len()) < threshold {
return ErrEqualOrLargerThreshold
}
Expand Down Expand Up @@ -241,8 +243,10 @@ func (bks BkParameters) GetAddShareCoefficient(ownBk, newBk *BkParameter, fieldO
newRankFactorial = newRankFactorial.Mod(newRankFactorial, fieldOrder)
}
for i := newrank; i < uint64(threshold); i++ {
// #nosec: G115: integer overflow conversion int -> uint32
factorialCoe := new(big.Int).Binomial(int64(i), int64(i-newrank))
factorialCoe = factorialCoe.Mul(factorialCoe, newRankFactorial)
// #nosec: G115: integer overflow conversion int -> uint32
tempbki := birkhoffMatrix.Get(i, uint64(ownIndex))
tempResult := new(big.Int).Mul(factorialCoe, xPower)
tempResult = tempResult.Mul(tempResult, tempbki)
Expand Down
4 changes: 4 additions & 0 deletions crypto/circuit/circuit.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ func (cir *Circuit) Garbled(kBit int, input []uint8, f EncFunc) (*GarbleCircuit,

// Generate others Circuit: XOR/AND/INV/EQ
var F []*HalfGateMessage
// #nosec: G115: integer overflow conversion int -> uint32
for i := int32(0); i < int32(len(cir.gates)); i++ {
g := cir.gates[i]
switch g.gate {
Expand Down Expand Up @@ -409,6 +410,7 @@ func (cir *Circuit) Garbled(kBit int, input []uint8, f EncFunc) (*GarbleCircuit,
func decrypt(d []int32, Y [][]byte) []uint8 {
result := make([]uint8, len(d))
for i := 0; i < len(d); i++ {
// #nosec: G115: integer overflow conversion int -> uint32
result[i] = uint8(d[i]) ^ lsb(Y[i])
}
return result
Expand Down Expand Up @@ -510,6 +512,7 @@ func setUint64ToBitSlice(input uint64) []uint8 {
result[i] = 0
}
for i := 0; i < big.BitLen(); i++ {
// #nosec: G115: integer overflow conversion int -> uint32
result[i] = uint8(big.Bit(i))
}
return result
Expand All @@ -525,6 +528,7 @@ func readText(scanner *bufio.Scanner) string {
func Decrypt(d []int32, Y [][]byte) []uint8 {
result := make([]uint8, len(d))
for i := 0; i < len(d); i++ {
// #nosec: G115: integer overflow conversion int -> uint32
result[i] = uint8(d[i]) ^ lsb(Y[i])
}
return result
Expand Down
1 change: 1 addition & 0 deletions crypto/circuit/circuit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ func setHexToIntSlice(input string, exptected uint8) []uint8 {
result[i] = 0
}
for i := 0; i < big.BitLen(); i++ {
// #nosec: G115: integer overflow conversion int -> uint32
result[i] = uint8(big.Bit(i))
}
return result
Expand Down
2 changes: 2 additions & 0 deletions crypto/dbnssystem/dbns.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ func get23ExpansionSpecialcase(numberwithout23Factor *big.Int, deepOfBranch int)
func getGivenDepth23Expansion(number *big.Int, upperDepth int) (*big.Int, []*expansion23, error) {
numberList := []*big.Int{number}
minPosition, exp2, exp3 := 0, 0, 0
// #nosec: G115: integer overflow conversion int -> uint32
upperDepthMinus1 := uint(upperDepth - 1)
var bStop bool
minValue := new(big.Int).Set(number)
Expand Down Expand Up @@ -226,6 +227,7 @@ func getMax2Factor(number *big.Int) (*big.Int, int) {
bitLength := number.BitLen()
for i := 0; i < bitLength; i++ {
if number.Bit(i) != 0 {
// #nosec: G115: integer overflow conversion int -> uint32
number.Rsh(number, uint(i))
return number, i
}
Expand Down
23 changes: 23 additions & 0 deletions crypto/elliptic/ed25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ import (
"crypto/elliptic"
"math/big"

ED25519 "crypto/ed25519"

"github.com/decred/dcrd/dcrec/edwards"
)

var (
big1 = big.NewInt(1)
ed25519Curve = &ed25519{
Curve: edwards.Edwards(),
}

BIP32ED25519 = "bip32"
)

type ed25519 struct {
Expand All @@ -40,3 +45,21 @@ func (ed *ed25519) Neg(x, y *big.Int) (*big.Int, *big.Int) {
negativeX := new(big.Int).Neg(x)
return negativeX.Mod(negativeX, ed.Params().P), new(big.Int).Set(y)
}

func (ed *ed25519) Type() string {
return "ed25519"
}

func (ed *ed25519) Slip10SeedList() []byte {
return []byte("ed25519 seed")
}

func (ed *ed25519) CompressedPublicKey(secret *big.Int, method string) []byte {
if method == BIP32ED25519 {
x, y := edwards.Edwards().ScalarBaseMult(secret.Bytes()[:32])
return edwards.BigIntPointToEncodedBytes(x, y)[:]
} else {
privateKey := ED25519.NewKeyFromSeed(secret.Bytes()[:32])
return privateKey[32:]
}
}
11 changes: 11 additions & 0 deletions crypto/elliptic/ed25519_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
package elliptic

import (
"encoding/hex"
"math/big"

. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
)

Expand All @@ -31,4 +33,13 @@ var _ = Describe("ed25519", func() {
Expect(negY.Cmp(scalY) == 0).Should(BeTrue())
})
})
// Test vectors : https://asecuritysite.com/ecc/eddsa4
DescribeTable("Compressed PubKey", func(secrethex string, expected string) {
secret, _ := new(big.Int).SetString(secrethex, 16)
Expect(hex.EncodeToString(Ed25519().CompressedPublicKey(secret, "test")) == expected).Should(BeTrue())
},
Entry("case1:", "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"),
Entry("case2:", "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"),
Entry("case3:", "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7", "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025"),
)
})
46 changes: 46 additions & 0 deletions crypto/elliptic/elliptic_curve.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,49 @@ func (c *ellipticCurve) Neg(x, y *big.Int) (*big.Int, *big.Int) {
NegY := new(big.Int).Neg(y)
return new(big.Int).Set(x), NegY.Mod(NegY, c.Curve.Params().P)
}

func (c *ellipticCurve) Type() string {
if c.Params().N.Cmp(p256Curve.Params().N) == 0 {
return "P256"
}
if c.Params().N.Cmp(secp256k1Curve.Params().N) == 0 {
return "secp256k1"
}
return "None"
}

func (c *ellipticCurve) Slip10SeedList() []byte {
if c.Params().N.Cmp(p256Curve.Params().N) == 0 {
return []byte("Bitcoin seed")
}
if c.Params().N.Cmp(secp256k1Curve.Params().N) == 0 {
return []byte("Bitcoin seed")
}
return []byte("None")
}

// WARN: Only support P256 and Secp256k1
func (c *ellipticCurve) CompressedPublicKey(secret *big.Int, method string) []byte {
/* Returns the compressed bytes for this point.
If pt.y is odd, 0x03 is pre-pended to pt.x.
If pt.y is even, 0x02 is pre-pended to pt.x.
Returns:
bytes: Compressed byte representation.
*/
x, y := c.ScalarBaseMult(secret.Bytes())
xBytePadding := x.Bytes()
if len(x.Bytes()) < 32 {
padding := make([]byte, 32-len(x.Bytes()))
xBytePadding = append(padding, xBytePadding...)
}
if new(big.Int).And(y, big1).Cmp(big1) == 0 {
padding := make([]byte, 1)
padding[0] = 3
xBytePadding = append(padding, xBytePadding...)
} else {
padding := make([]byte, 1)
padding[0] = 2
xBytePadding = append(padding, xBytePadding...)
}
return xBytePadding
}
3 changes: 3 additions & 0 deletions crypto/elliptic/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ type Curve interface {
elliptic.Curve

Neg(x1, y1 *big.Int) (x, y *big.Int)
Type() string
Slip10SeedList() []byte
CompressedPublicKey(secret *big.Int, method string) []byte
}
10 changes: 10 additions & 0 deletions crypto/elliptic/secp256k1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
package elliptic

import (
"encoding/hex"
"math/big"
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
)

Expand All @@ -32,6 +34,14 @@ var _ = Describe("secp256k1", func() {
Expect(negY.Cmp(scalY) == 0).Should(BeTrue())
})
})

DescribeTable("Compressed PubKey", func(secrethex string, expected string) {
secret, _ := new(big.Int).SetString(secrethex, 16)
Expect(hex.EncodeToString(Secp256k1().CompressedPublicKey(secret, "test")) == expected).Should(BeTrue())
},
Entry("case1:", "f91d8f3a49805fff9289769247e984b355939679f3080156fe295229e00f25af", "0252972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2"),
Entry("case2:", "ac609e0cc9681f8cb63e968be20e0f19721751561944f5b4e52d54d5f27ec57b", "0318ed2e1ec629e2d3dae7be1103d4f911c24e0c80e70038f5eb5548245c475f50"),
)
})

func TestEllipticcurve(t *testing.T) {
Expand Down
Loading