Skip to content

Commit

Permalink
Merge branch 'main' into recid
Browse files Browse the repository at this point in the history
  • Loading branch information
veorq authored May 5, 2023
2 parents d44e983 + 88deb90 commit e629aab
Show file tree
Hide file tree
Showing 16 changed files with 351 additions and 13 deletions.
7 changes: 3 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0
github.com/fxamacker/cbor/v2 v2.3.0
github.com/rs/zerolog v1.23.0
github.com/stretchr/testify v1.7.0
github.com/zeebo/blake3 v0.2.0
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/crypto v0.1.0
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
)
51 changes: 51 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
github.com/aws/aws-sdk-go v1.44.238 h1:qSWVXr/y/SsYyuvwVHYQpzcMKa2UzOjKgqPp7BTGfbo=
github.com/aws/aws-sdk-go v1.44.238/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v1.17.7 h1:CLSjnhJSTSogvqUGhIC6LqFKATMRexcxLZ0i/Nzk9Eg=
github.com/aws/aws-sdk-go-v2 v1.17.7/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
github.com/aws/aws-sdk-go-v2/config v1.18.19 h1:AqFK6zFNtq4i1EYu+eC7lcKHYnZagMn6SW171la0bGw=
github.com/aws/aws-sdk-go-v2/config v1.18.19/go.mod h1:XvTmGMY8d52ougvakOv1RpiTLPz9dlG/OQHsKU/cMmY=
github.com/aws/aws-sdk-go-v2/credentials v1.13.18 h1:EQMdtHwz0ILTW1hoP+EwuWhwCG1hD6l3+RWFQABET4c=
github.com/aws/aws-sdk-go-v2/credentials v1.13.18/go.mod h1:vnwlwjIe+3XJPBYKu1et30ZPABG3VaXJYr8ryohpIyM=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.1 h1:gt57MN3liKiyGopcqgNzJb2+d9MJaKT/q1OksHNXVE4=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.1/go.mod h1:lfUx8puBRdM5lVVMQlwt2v+ofiG/X6Ms+dy0UkG/kXw=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.31 h1:sJLYcS+eZn5EeNINGHSCRAwUJMFVqklwkH36Vbyai7M=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.31/go.mod h1:QT0BqUvX1Bh2ABdTGnjqEjvjzrCfIniM9Sc8zn9Yndo=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.25 h1:1mnRASEKnkqsntcxHaysxwgVoUUp5dkiB+l3llKnqyg=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.25/go.mod h1:zBHOPwhBc3FlQjQJE/D3IfPWiWaQmT06Vq9aNukDo0k=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.32 h1:p5luUImdIqywn6JpQsW3tq5GNOxKmOnEpybzPx+d1lk=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.32/go.mod h1:XGhIBZDEgfqmFIugclZ6FU7v75nHhBDtzuB4xB/tEi4=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.25 h1:5LHn8JQ0qvjD9L9JhMtylnkcw7j05GDZqM9Oin6hpr0=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.25/go.mod h1:/95IA+0lMnzW6XzqYJRpjjsAbKEORVeO0anQqjd2CNU=
github.com/aws/aws-sdk-go-v2/service/kms v1.20.8 h1:R5f4VOFi3ScTe7TtePyxLqEhNqTJIAxL57MzrXFNs6I=
github.com/aws/aws-sdk-go-v2/service/kms v1.20.8/go.mod h1:OtP3pBOgmJM+acQyQcQXtQHets3yJoVuanCx2T5M7v4=
github.com/aws/aws-sdk-go-v2/service/sso v1.12.6 h1:5V7DWLBd7wTELVz5bPpwzYy/sikk0gsgZfj40X+l5OI=
github.com/aws/aws-sdk-go-v2/service/sso v1.12.6/go.mod h1:Y1VOmit/Fn6Tz1uFAeCO6Q7M2fmfXSCLeL5INVYsLuY=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.6 h1:B8cauxOH1W1v7rd8RdI/MWnoR4Ze0wIHWrb90qczxj4=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.6/go.mod h1:Lh/bc9XUf8CfOY6Jp5aIkQtN+j1mc+nExc+KXj9jx2s=
github.com/aws/aws-sdk-go-v2/service/sts v1.18.7 h1:bWNgNdRko2x6gqa0blfATqAZKZokPIeM1vfmQt2pnvM=
github.com/aws/aws-sdk-go-v2/service/sts v1.18.7/go.mod h1:JuTnSoeePXmMVe9G8NcjjwgOKEfZ4cOjMuT2IBT/2eI=
github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8=
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cronokirby/safenum v0.29.0 h1:kf1/8vvN/yQjrZU3tR/vDb5OdIQp2uJ6WvPVbU61J+E=
github.com/cronokirby/safenum v0.29.0/go.mod h1:AWp82xwEqKcnrpJPXPa1m0gF/OY8dzgL17ubUBnVygA=
Expand All @@ -11,6 +39,10 @@ github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0/go.mod h1:J70FGZSbzsjecRTiTzER+
github.com/fxamacker/cbor/v2 v2.3.0 h1:aM45YGMctNakddNNAezPxDUpv38j44Abh+hifNuqXik=
github.com/fxamacker/cbor/v2 v2.3.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand All @@ -28,6 +60,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/blake3 v0.2.0 h1:1SGx3IvKWFUU/xl+/7kjdcjjMcvVSm+3dMo/N42afC8=
Expand All @@ -39,15 +72,23 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand All @@ -57,17 +98,27 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 h1:rw6UNGRMfarCepjI8qOepea/SXwIBVfTKjztZ5gBbq4=
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
40 changes: 40 additions & 0 deletions pkg/ecdsa/signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,43 @@ func (sig Signature) RecoveryId() byte {

return recid
}

// get a signature in ethereum format
func (sig Signature) SigEthereum() ([]byte, error) {
IsOverHalfOrder := sig.S.IsOverHalfOrder() // s-values greater than secp256k1n/2 are considered invalid

if IsOverHalfOrder {
sig.S.Negate()
}

r, err := sig.R.MarshalBinary()
if err != nil {
return nil, err
}
s, err := sig.S.MarshalBinary()
if err != nil {
return nil, err
}

rs := make([]byte, 0, 65)
rs = append(rs, r...)
rs = append(rs, s...)

if IsOverHalfOrder {
v := rs[0] - 2 // Convert to Ethereum signature format with 'recovery id' v at the end.
copy(rs, rs[1:])
rs[64] = v ^ 1
} else {
v := rs[0] - 2
copy(rs, rs[1:])
rs[64] = v
}

r[0] = rs[64] + 2
if err := sig.R.UnmarshalBinary(r); err != nil {
return nil, err
}

return rs, nil
}

8 changes: 8 additions & 0 deletions pkg/math/arith/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,11 @@ func IsInIntervalLPrimeEps(n *safenum.Int) bool {
}
return n.TrueLen() <= params.LPrimePlusEpsilon
}

// IsInIntervalLEpsPlus1RootN returns true if n ∈ [-2¹⁺ˡ⁺ᵉ√N,…,2¹⁺ˡ⁺ᵉ√N], for a Paillier modulus N.
func IsInIntervalLEpsPlus1RootN(n *safenum.Int) bool {
if n == nil {
return false
}
return n.TrueLen() <= 1+params.LPlusEpsilon+(params.BitsIntModN/2)
}
2 changes: 2 additions & 0 deletions pkg/math/curve/curve.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ type Scalar interface {
//
// This can be accomplished with Act, but can be made more efficient, in many cases.
ActOnBase() Point

IsOverHalfOrder() bool
}

// Point represents an element of our Elliptic Curve group.
Expand Down
4 changes: 4 additions & 0 deletions pkg/math/curve/secp256k1.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ func (s *Secp256k1Scalar) Negate() Scalar {
return s
}

func (s *Secp256k1Scalar) IsOverHalfOrder() bool {
return s.value.IsOverHalfOrder()
}

func (s *Secp256k1Scalar) Equal(that Scalar) bool {
other := secp256k1CastScalar(that)

Expand Down
20 changes: 20 additions & 0 deletions pkg/math/sample/plus_minus.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ func IntervalLPrime(rand io.Reader) *safenum.Int {
return sampleNeg(rand, params.LPrime)
}

// IntervalEps returns an integer in the range ± 2ᵉ, but with constant-time properties.
func IntervalEps(rand io.Reader) *safenum.Int {
return sampleNeg(rand, params.Epsilon)
}

// IntervalLEps returns an integer in the range ± 2ˡ⁺ᵉ, but with constant-time properties.
func IntervalLEps(rand io.Reader) *safenum.Int {
return sampleNeg(rand, params.LPlusEpsilon)
Expand All @@ -43,11 +48,26 @@ func IntervalLN(rand io.Reader) *safenum.Int {
return sampleNeg(rand, params.L+params.BitsIntModN)
}

// IntervalLN2 returns an integer in the range ± 2ˡ•N², where N is the size of a Paillier modulus.
func IntervalLN2(rand io.Reader) *safenum.Int {
return sampleNeg(rand, params.L+(2*params.BitsIntModN))
}

// IntervalLEpsN returns an integer in the range ± 2ˡ⁺ᵉ•N, where N is the size of a Paillier modulus.
func IntervalLEpsN(rand io.Reader) *safenum.Int {
return sampleNeg(rand, params.LPlusEpsilon+params.BitsIntModN)
}

// IntervalLEpsN2 returns an integer in the range ± 2ˡ⁺ᵉ•N², where N is the size of a Paillier modulus.
func IntervalLEpsN2(rand io.Reader) *safenum.Int {
return sampleNeg(rand, params.LPlusEpsilon+(2*params.BitsIntModN))
}

// IntervalLEpsRootN returns an integer in the range ± 2ˡ⁺ᵉ•√N, where N is the size of a Paillier modulus.
func IntervalLEpsRootN(rand io.Reader) *safenum.Int {
return sampleNeg(rand, params.LPlusEpsilon+(params.BitsIntModN/2))
}

// IntervalScalar returns an integer in the range ±q, with q the size of a Scalar.
func IntervalScalar(rand io.Reader, group curve.Curve) *safenum.Int {
return sampleNeg(rand, group.ScalarBits())
Expand Down
3 changes: 3 additions & 0 deletions pkg/pedersen/pedersen.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ func ValidateParameters(n *safenum.Modulus, s, t *safenum.Nat) error {
// N = p•q, p ≡ q ≡ 3 mod 4.
func (p Parameters) N() *safenum.Modulus { return p.n.Modulus }

// N, but as an arith modulus, which is sometimes useful
func (p Parameters) NArith() *arith.Modulus { return p.n }

// S = r² mod N.
func (p Parameters) S() *safenum.Nat { return p.s }

Expand Down
153 changes: 153 additions & 0 deletions pkg/zk/fac/fac.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package zkfac

import (
"crypto/rand"

"github.com/cronokirby/safenum"
"github.com/taurusgroup/multi-party-sig/pkg/hash"
"github.com/taurusgroup/multi-party-sig/pkg/math/arith"
"github.com/taurusgroup/multi-party-sig/pkg/math/sample"
"github.com/taurusgroup/multi-party-sig/pkg/pedersen"
)

type Public struct {
Aux *pedersen.Parameters
}

type Private struct {
P, Q *safenum.Nat
}

type Commitment struct {
P *safenum.Nat
Q *safenum.Nat
A *safenum.Nat
B *safenum.Nat
T *safenum.Nat
}

type Proof struct {
Comm Commitment
Sigma *safenum.Int
Z1 *safenum.Int
Z2 *safenum.Int
W1 *safenum.Int
W2 *safenum.Int
V *safenum.Int
}

func NewProof(private Private, hash *hash.Hash, public Public) *Proof {
N := public.Aux.NArith()

// Figure 28, point 1.
alpha := sample.IntervalLEpsRootN(rand.Reader)
beta := sample.IntervalLEpsRootN(rand.Reader)
mu := sample.IntervalLN(rand.Reader)
nu := sample.IntervalLN(rand.Reader)
sigma := sample.IntervalLN2(rand.Reader)
r := sample.IntervalLEpsN2(rand.Reader)
x := sample.IntervalLEpsN(rand.Reader)
y := sample.IntervalLEpsN(rand.Reader)

pInt := new(safenum.Int).SetNat(private.P)
qInt := new(safenum.Int).SetNat(private.Q)
P := public.Aux.Commit(pInt, mu)
Q := public.Aux.Commit(qInt, nu)
A := public.Aux.Commit(alpha, x)
B := public.Aux.Commit(beta, y)
T := N.ExpI(Q, alpha)
T.ModMul(T, N.ExpI(public.Aux.T(), r), N.Modulus)

comm := Commitment{P, Q, A, B, T}

// Figure 28, point 2:
e, _ := challenge(hash, public, comm)

// Figure 28, point 3:
// "..., and sends (z, u, v) to the verifier, where"
// DEVIATION:
// This seems like another typo, because there's no "u",
// so I assume they meant "sends (z1, z2, w1, w2, v)".
z1 := new(safenum.Int).Mul(e, pInt, -1)
z1.Add(z1, alpha, -1)
z2 := new(safenum.Int).Mul(e, qInt, -1)
z2.Add(z2, beta, -1)
w1 := new(safenum.Int).Mul(e, mu, -1)
w1.Add(w1, x, -1)
w2 := new(safenum.Int).Mul(e, nu, -1)
w2.Add(w2, y, -1)
sigmaHat := new(safenum.Int).Mul(nu, pInt, -1)
sigmaHat = sigmaHat.Neg(1)
sigmaHat.Add(sigmaHat, sigma, -1)
v := new(safenum.Int).Mul(e, sigmaHat, -1)
v.Add(v, r, -1)

return &Proof{
Comm: comm,
Sigma: sigma,
Z1: z1,
Z2: z2,
W1: w1,
W2: w2,
V: v,
}
}

func (p *Proof) Verify(public Public, hash *hash.Hash) bool {
if p == nil {
return false
}

e, err := challenge(hash, public, p.Comm)
if err != nil {
return false
}

N := public.Aux.N()
NArith := public.Aux.NArith()
// Setting R this way avoid issues with the other exponent functions which
// might try and apply the CRT.
R := new(safenum.Nat).SetNat(public.Aux.S())
R.ExpI(R, new(safenum.Int).SetNat(N.Nat()), N)
R.ModMul(R, NArith.ExpI(public.Aux.T(), p.Sigma), N)

lhs := public.Aux.Commit(p.Z1, p.W1)
rhs := NArith.ExpI(p.Comm.P, e)
rhs.ModMul(rhs, p.Comm.A, N)
if lhs.Eq(rhs) != 1 {
return false
}

lhs = public.Aux.Commit(p.Z2, p.W2)
rhs = NArith.ExpI(p.Comm.Q, e)
rhs.ModMul(rhs, p.Comm.B, N)
if lhs.Eq(rhs) != 1 {
return false
}

lhs = NArith.ExpI(p.Comm.Q, p.Z1)
lhs.ModMul(lhs, NArith.ExpI(public.Aux.T(), p.V), N)
rhs = NArith.ExpI(R, e)
rhs.ModMul(rhs, p.Comm.T, N)
if lhs.Eq(rhs) != 1 {
return false
}

// DEVIATION: for the bounds to work, we add an extra bit, to ensure that we don't have spurious failures.
return arith.IsInIntervalLEpsPlus1RootN(p.Z1) && arith.IsInIntervalLEpsPlus1RootN(p.Z2)
}

func challenge(hash *hash.Hash, public Public, commitment Commitment) (*safenum.Int, error) {
err := hash.WriteAny(public.Aux, commitment.P, commitment.Q, commitment.A, commitment.B, commitment.T)
if err != nil {
return nil, err
}
// Figure 28, point 2:
// "Verifier replies with e <- +-q"
// DEVIATION:
// This doesn't make any sense, since we don't know the secret factor q,
// and involving the size of scalars doesn't make sense.
// I think that this is a typo in the paper, and instead it should
// be +-2^eps.
return sample.IntervalEps(hash.Digest()), nil
}
Loading

0 comments on commit e629aab

Please sign in to comment.