@ -2,6 +2,7 @@
// http://www.isecure-journal.com/article_39171_47f9ec605dd3918c2793565ec21fcd7a.pdf
// http://www.isecure-journal.com/article_39171_47f9ec605dd3918c2793565ec21fcd7a.pdf
//
//
// LICENSE can be found at https://github.com/arnaucube/go-blindsecp256k1/blob/master/LICENSE
// LICENSE can be found at https://github.com/arnaucube/go-blindsecp256k1/blob/master/LICENSE
//
package blindsecp256k1
package blindsecp256k1
// WARNING: WIP code
// WARNING: WIP code
@ -14,20 +15,24 @@ import (
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
)
)
type Point struct {
X * big . Int
Y * big . Int
}
var (
var (
// G represents the base point of secp256k1
G * Point = & Point {
G * Point = & Point {
X : secp256k1 . S256 ( ) . Gx ,
X : secp256k1 . S256 ( ) . Gx ,
Y : secp256k1 . S256 ( ) . Gy ,
Y : secp256k1 . S256 ( ) . Gy ,
}
}
// N represents the order of G of secp256k1
N * big . Int = secp256k1 . S256 ( ) . N
N * big . Int = secp256k1 . S256 ( ) . N
)
)
// Point represents a point on the secp256k1 curve
type Point struct {
X * big . Int
Y * big . Int
}
// Add performs the Point addition
func ( p * Point ) Add ( q * Point ) * Point {
func ( p * Point ) Add ( q * Point ) * Point {
x , y := secp256k1 . S256 ( ) . Add ( p . X , p . Y , q . X , q . Y )
x , y := secp256k1 . S256 ( ) . Add ( p . X , p . Y , q . X , q . Y )
return & Point {
return & Point {
@ -36,6 +41,7 @@ func (p *Point) Add(q *Point) *Point {
}
}
}
}
// Mul performs the Point scalar multiplication
func ( p * Point ) Mul ( scalar * big . Int ) * Point {
func ( p * Point ) Mul ( scalar * big . Int ) * Point {
x , y := secp256k1 . S256 ( ) . ScalarMult ( p . X , p . Y , scalar . Bytes ( ) )
x , y := secp256k1 . S256 ( ) . ScalarMult ( p . X , p . Y , scalar . Bytes ( ) )
return & Point {
return & Point {
@ -44,6 +50,7 @@ func (p *Point) Mul(scalar *big.Int) *Point {
}
}
}
}
// WIP
func newRand ( ) * big . Int {
func newRand ( ) * big . Int {
var b [ 32 ] byte
var b [ 32 ] byte
_ , err := rand . Read ( b [ : ] )
_ , err := rand . Read ( b [ : ] )
@ -54,108 +61,129 @@ func newRand() *big.Int {
return new ( big . Int ) . Mod ( bi , N )
return new ( big . Int ) . Mod ( bi , N )
}
}
// PrivateKey represents the signer's private key
type PrivateKey big . Int
type PrivateKey big . Int
// PublicKey represents the signer's public key
type PublicKey Point
type PublicKey Point
// NewPrivateKey returns a new random private key
func NewPrivateKey ( ) * PrivateKey {
func NewPrivateKey ( ) * PrivateKey {
k := newRand ( )
k := newRand ( )
sk := PrivateKey ( * k )
sk := PrivateKey ( * k )
return & sk
return & sk
}
}
// BigInt returns a *big.Int representation of the PrivateKey
func ( sk * PrivateKey ) BigInt ( ) * big . Int {
func ( sk * PrivateKey ) BigInt ( ) * big . Int {
return ( * big . Int ) ( sk )
return ( * big . Int ) ( sk )
}
}
// Public returns the PublicKey from the PrivateKey
func ( sk * PrivateKey ) Public ( ) * PublicKey {
func ( sk * PrivateKey ) Public ( ) * PublicKey {
Q := G . Mul ( sk . BigInt ( ) )
Q := G . Mul ( sk . BigInt ( ) )
pk := PublicKey ( * Q )
pk := PublicKey ( * Q )
return & pk
return & pk
}
}
// Point returns a *Point representation of the PublicKey
func ( pk * PublicKey ) Point ( ) * Point {
func ( pk * PublicKey ) Point ( ) * Point {
return ( * Point ) ( pk )
return ( * Point ) ( pk )
}
}
// SignerPrivateData contains the secret values from the Signer
type SignerPrivateData struct {
type SignerPrivateData struct {
d * PrivateKey
k * big . Int
D * PrivateKey
K * big . Int
}
}
// SignerPublicData contains the public values from the Signer (generated from
// its SignerPrivateData)
type SignerPublicData struct {
type SignerPublicData struct {
// Q is the Signer Public Key
// Q is the Signer Public Key
Q * PublicKey // = skG
Q * PublicKey // = skG
R * Point // = kG
R * Point // = kG
}
}
// NewSigner returns a new SignerPrivateData with random D & K
func NewSigner ( ) * SignerPrivateData {
func NewSigner ( ) * SignerPrivateData {
sk := NewPrivateKey ( )
sk := NewPrivateKey ( )
k := newRand ( )
k := newRand ( )
return & SignerPrivateData {
return & SignerPrivateData {
d : sk ,
k : k ,
D : sk ,
K : k ,
}
}
}
}
// PublicData returns the SignerPublicData from the SignerPrivateData
func ( signer * SignerPrivateData ) PublicData ( ) * SignerPublicData {
func ( signer * SignerPrivateData ) PublicData ( ) * SignerPublicData {
return & SignerPublicData {
return & SignerPublicData {
Q : signer . d . Public ( ) , // Q = dG
R : G . Mul ( signer . k ) , // R = kG
Q : signer . D . Public ( ) , // Q = dG
R : G . Mul ( signer . K ) , // R = kG
}
}
}
}
// BlindSign performs the blind signature on the given mBlinded using
// SignerPrivateData values
func ( signer * SignerPrivateData ) BlindSign ( mBlinded * big . Int ) * big . Int {
func ( signer * SignerPrivateData ) BlindSign ( mBlinded * big . Int ) * big . Int {
// TODO add pending checks
// TODO add pending checks
// s' = d(m') + k
// s' = d(m') + k
sBlind := new ( big . Int ) . Add (
sBlind := new ( big . Int ) . Add (
new ( big . Int ) . Mul ( signer . d . BigInt ( ) , mBlinded ) ,
signer . k )
new ( big . Int ) . Mul ( signer . D . BigInt ( ) , mBlinded ) ,
signer . K )
return sBlind
return sBlind
}
}
// UserSecretData contains the secret values from the User (a, b, c) and the
// public F
type UserSecretData struct {
type UserSecretData struct {
a * big . Int
b * big . Int
c * big . Int
A * big . Int
B * big . Int
C * big . Int
F * Point // public
F * Point // public
}
}
// Blind performs the blinding operation on m using SignerPublicData parameters
func Blind ( m * big . Int , signer * SignerPublicData ) ( * big . Int , * UserSecretData ) {
func Blind ( m * big . Int , signer * SignerPublicData ) ( * big . Int , * UserSecretData ) {
u := & UserSecretData { }
u := & UserSecretData { }
u . a = newRand ( )
u . b = newRand ( )
u . c = newRand ( )
binv := new ( big . Int ) . ModInverse ( u . b , N )
u . A = newRand ( )
u . B = newRand ( )
u . C = newRand ( )
binv := new ( big . Int ) . ModInverse ( u . B , N )
// F = b^-1 R + a b^-1 Q + c G
// F = b^-1 R + a b^-1 Q + c G
bR := signer . R . Mul ( binv )
bR := signer . R . Mul ( binv )
abinv := new ( big . Int ) . Mul ( u . a , binv )
abinv := new ( big . Int ) . Mul ( u . A , binv )
abinv = new ( big . Int ) . Mod ( abinv , N )
abinv = new ( big . Int ) . Mod ( abinv , N )
abQ := signer . Q . Point ( ) . Mul ( abinv )
abQ := signer . Q . Point ( ) . Mul ( abinv )
cG := G . Mul ( u . c )
cG := G . Mul ( u . C )
u . F = bR . Add ( abQ ) . Add ( cG )
u . F = bR . Add ( abQ ) . Add ( cG )
// TODO check F==O
// TODO check F==O
r := new ( big . Int ) . Mod ( u . F . X , N )
r := new ( big . Int ) . Mod ( u . F . X , N )
// m' = br(m)+a
// m' = br(m)+a
br := new ( big . Int ) . Mul ( u . b , r )
br := new ( big . Int ) . Mul ( u . B , r )
brm := new ( big . Int ) . Mul ( br , m )
brm := new ( big . Int ) . Mul ( br , m )
mBlinded := new ( big . Int ) . Add ( brm , u . a )
mBlinded := new ( big . Int ) . Add ( brm , u . A )
mBlinded = new ( big . Int ) . Mod ( mBlinded , N )
mBlinded = new ( big . Int ) . Mod ( mBlinded , N )
return mBlinded , u
return mBlinded , u
}
}
// Signature contains the signature values S & F
type Signature struct {
type Signature struct {
S * big . Int
S * big . Int
F * Point
F * Point
}
}
// Unblind performs the unblinding operation of the blinded signature for the
// given message m and the UserSecretData
func Unblind ( sBlind , m * big . Int , u * UserSecretData ) * Signature {
func Unblind ( sBlind , m * big . Int , u * UserSecretData ) * Signature {
// s = b^-1 s' + c
// s = b^-1 s' + c
binv := new ( big . Int ) . ModInverse ( u . b , N )
binv := new ( big . Int ) . ModInverse ( u . B , N )
bs := new ( big . Int ) . Mul ( binv , sBlind )
bs := new ( big . Int ) . Mul ( binv , sBlind )
s := new ( big . Int ) . Add ( bs , u . c )
s := new ( big . Int ) . Add ( bs , u . C )
s = new ( big . Int ) . Mod ( s , N )
s = new ( big . Int ) . Mod ( s , N )
return & Signature {
return & Signature {
@ -164,6 +192,7 @@ func Unblind(sBlind, m *big.Int, u *UserSecretData) *Signature {
}
}
}
}
// Verify checks the signature of the message m for the given PublicKey
func Verify ( m * big . Int , signature * Signature , q * PublicKey ) bool {
func Verify ( m * big . Int , signature * Signature , q * PublicKey ) bool {
// TODO add pending checks
// TODO add pending checks
sG := G . Mul ( signature . S ) // sG
sG := G . Mul ( signature . S ) // sG