-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from MixinNetwork/macos-arm
support macOS arm64
- Loading branch information
Showing
3 changed files
with
298 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
package api | ||
|
||
import ( | ||
"encoding/binary" | ||
|
||
"github.com/bwesterb/go-ristretto" | ||
"golang.org/x/crypto/sha3" | ||
) | ||
|
||
type PedersenGens struct { | ||
B *ristretto.Point | ||
BBlinding *ristretto.Point | ||
} | ||
|
||
func NewPedersenGens() *PedersenGens { | ||
var base ristretto.Point | ||
base.SetBase() | ||
|
||
return &PedersenGens{ | ||
B: hashToPoint(&base), | ||
BBlinding: &base, | ||
} | ||
} | ||
|
||
func DefaultPedersenGens() *PedersenGens { | ||
var base ristretto.Point | ||
base.SetBase() | ||
|
||
h := sha3.New512() | ||
h.Write(base.Bytes()) | ||
|
||
return &PedersenGens{ | ||
B: &base, | ||
BBlinding: pointFromUniformBytes(h.Sum(nil)), | ||
} | ||
} | ||
|
||
// CommitPedersenGens includes multiscalar_mul | ||
func (pg *PedersenGens) Commit(value, blinding *ristretto.Scalar) *ristretto.Point { | ||
return multiscalarMul([]*ristretto.Scalar{value, blinding}, []*ristretto.Point{pg.B, pg.BBlinding}) | ||
} | ||
|
||
type BulletproofGens struct { | ||
GensCapacity int64 | ||
PartyCapacity int64 | ||
GVec [][]*ristretto.Point | ||
HVec [][]*ristretto.Point | ||
} | ||
|
||
func NewBulletproofGens(gensCapacity, partyCapacity int64) *BulletproofGens { | ||
b := &BulletproofGens{ | ||
GensCapacity: 0, | ||
PartyCapacity: partyCapacity, | ||
GVec: make([][]*ristretto.Point, partyCapacity), | ||
HVec: make([][]*ristretto.Point, partyCapacity), | ||
} | ||
b.IncreaseCapacity(gensCapacity) | ||
return b | ||
} | ||
|
||
func (b *BulletproofGens) IncreaseCapacity(capacity int64) { | ||
if b.GensCapacity >= capacity { | ||
return | ||
} | ||
for i := 0; i < int(b.PartyCapacity); i++ { | ||
var byte32 [4]byte | ||
binary.LittleEndian.PutUint32(byte32[:], uint32(i)) | ||
label := []byte("G") | ||
label = append(label, byte32[:]...) | ||
chainG := NewGeneratorsChain(label) | ||
chainG.FastForward(b.GensCapacity) | ||
|
||
genPoints := make([]*ristretto.Point, capacity-b.GensCapacity) | ||
for j := 0; j < int(capacity-b.GensCapacity); j++ { | ||
genPoints[j] = chainG.Next() | ||
} | ||
b.GVec[i] = genPoints | ||
|
||
label[0] = []byte("H")[0] | ||
chainP := NewGeneratorsChain(label) | ||
chainP.FastForward(b.GensCapacity) | ||
partyPoints := make([]*ristretto.Point, capacity-b.GensCapacity) | ||
for j := 0; j < int(capacity-b.GensCapacity); j++ { | ||
partyPoints[j] = chainP.Next() | ||
} | ||
b.HVec[i] = partyPoints | ||
} | ||
b.GensCapacity = capacity | ||
} | ||
|
||
func (b *BulletproofGens) G(n, m int64) *AggregatedGensIter { | ||
return &AggregatedGensIter{ | ||
N: n, | ||
M: m, | ||
Array: b.GVec, | ||
PartyIdX: 0, | ||
GenIdX: 0, | ||
} | ||
} | ||
|
||
func (b *BulletproofGens) H(n, m int64) *AggregatedGensIter { | ||
return &AggregatedGensIter{ | ||
N: n, | ||
M: m, | ||
Array: b.HVec, | ||
PartyIdX: 0, | ||
GenIdX: 0, | ||
} | ||
} | ||
|
||
type AggregatedGensIter struct { | ||
Array [][]*ristretto.Point | ||
N, M int64 | ||
PartyIdX int64 | ||
GenIdX int64 | ||
} | ||
|
||
func (a *AggregatedGensIter) Next() *ristretto.Point { | ||
if a.GenIdX >= a.N { | ||
a.GenIdX = 0 | ||
a.PartyIdX += 1 | ||
} | ||
if a.PartyIdX >= a.M { | ||
return nil | ||
} | ||
cur_gen := a.GenIdX | ||
a.GenIdX += 1 | ||
return a.Array[a.PartyIdX][cur_gen] | ||
} | ||
|
||
type GeneratorsChain struct { | ||
sha3.ShakeHash | ||
} | ||
|
||
func NewGeneratorsChain(label []byte) *GeneratorsChain { | ||
h := sha3.NewShake256() | ||
h.Write([]byte("GeneratorsChain")) | ||
h.Write(label) | ||
return &GeneratorsChain{h} | ||
} | ||
|
||
func (c *GeneratorsChain) FastForward(n int64) { | ||
for i := 0; i < int(n); i++ { | ||
var data [64]byte | ||
c.Read(data[:]) | ||
} | ||
} | ||
|
||
func (c *GeneratorsChain) Next() *ristretto.Point { | ||
var data [64]byte | ||
c.Read(data[:]) | ||
return pointFromUniformBytes(data[:]) | ||
} | ||
|
||
func pointFromUniformBytes(key []byte) *ristretto.Point { | ||
var r1Bytes, r2Bytes [32]byte | ||
copy(r1Bytes[:], key[:32]) | ||
copy(r2Bytes[:], key[32:]) | ||
var r, r1, r2 ristretto.Point | ||
return r.Add(r1.SetElligator(&r1Bytes), r2.SetElligator(&r2Bytes)) | ||
} | ||
|
||
type BulletproofGensShare struct { | ||
Gens *BulletproofGens | ||
Share int | ||
} | ||
|
||
func (g *BulletproofGens) Share(j int) *BulletproofGensShare { | ||
return &BulletproofGensShare{ | ||
Gens: g, | ||
Share: j, | ||
} | ||
} | ||
|
||
func (g *BulletproofGensShare) G(n int64) []*ristretto.Point { | ||
return g.Gens.GVec[g.Share][:n] | ||
} | ||
|
||
func (g *BulletproofGensShare) H(n int64) []*ristretto.Point { | ||
return g.Gens.HVec[g.Share][:n] | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package api | ||
|
||
import ( | ||
"encoding/binary" | ||
"encoding/hex" | ||
|
||
"github.com/bwesterb/go-ristretto" | ||
"github.com/dchest/blake2b" | ||
account "github.com/jadeydi/mobilecoin-account" | ||
) | ||
|
||
func keyImage(private *ristretto.Scalar) *ristretto.Point { | ||
var p ristretto.Point | ||
p.ScalarMultBase(private) | ||
|
||
hash := blake2b.New512() | ||
hash.Write([]byte(HASH_TO_POINT_DOMAIN_TAG)) | ||
hash.Write([]byte(p.Bytes())) | ||
var key [64]byte | ||
copy(key[:], hash.Sum(nil)) | ||
|
||
var r1Bytes, r2Bytes [32]byte | ||
copy(r1Bytes[:], key[:32]) | ||
copy(r2Bytes[:], key[32:]) | ||
var r, r1, r2 ristretto.Point | ||
return r.Add(r1.SetElligator(&r1Bytes), r2.SetElligator(&r2Bytes)) | ||
} | ||
|
||
func GetValueWithBlinding(output *TxOut, viewPrivate *ristretto.Scalar) (uint64, *ristretto.Scalar) { | ||
secret := createSharedSecret(hexToPoint(output.PublicKey), viewPrivate) | ||
|
||
mask := GetValueMask(secret) | ||
maskedValue := uint64(output.Amount.MaskedValue) | ||
value := maskedValue ^ mask | ||
|
||
blinding := GetBlinding(secret) | ||
return value, blinding | ||
} | ||
|
||
func GetValueWithBlindingNew(viewPrivate, publicKey string, maskedValue uint64) (uint64, *ristretto.Scalar) { | ||
secret := account.SharedSecret(viewPrivate, publicKey) | ||
mask := GetValueMask(secret) | ||
value := maskedValue ^ mask | ||
blinding := GetBlinding(secret) | ||
return value, blinding | ||
} | ||
|
||
func GetValueMask(secret *ristretto.Point) uint64 { | ||
hash := blake2b.New512() | ||
hash.Write([]byte(AMOUNT_VALUE_DOMAIN_TAG)) | ||
hash.Write(secret.Bytes()) | ||
|
||
var hs ristretto.Scalar | ||
var key [64]byte | ||
copy(key[:], hash.Sum(nil)) | ||
return binary.LittleEndian.Uint64(hs.SetReduced(&key).Bytes()[:8]) | ||
} | ||
|
||
func GetBlinding(secret *ristretto.Point) *ristretto.Scalar { | ||
hash := blake2b.New512() | ||
hash.Write([]byte(AMOUNT_BLINDING_DOMAIN_TAG)) | ||
hash.Write(secret.Bytes()) | ||
|
||
var hs ristretto.Scalar | ||
var key [64]byte | ||
copy(key[:], hash.Sum(nil)) | ||
return hs.SetReduced(&key) | ||
} | ||
|
||
func NewCommitment(value uint64, blinding *ristretto.Scalar) *ristretto.Point { | ||
// value scalar | ||
v := uint64ToScalar(value) | ||
|
||
generators := NewPedersenGens() | ||
return generators.Commit(v, blinding) | ||
} | ||
|
||
func generatorsBlinding(base *ristretto.Point) *ristretto.Point { | ||
hash := blake2b.New512() | ||
hash.Write([]byte(HASH_TO_POINT_DOMAIN_TAG)) | ||
hash.Write(base.Bytes()) | ||
var key [64]byte | ||
copy(key[:], hash.Sum(nil)) | ||
|
||
var r1Bytes, r2Bytes [32]byte | ||
copy(r1Bytes[:], key[:32]) | ||
copy(r2Bytes[:], key[32:]) | ||
var r, r1, r2 ristretto.Point | ||
return r.Add(r1.SetElligator(&r1Bytes), r2.SetElligator(&r2Bytes)) | ||
} | ||
|
||
func RecoverPublicSubaddressSpendKey(viewPrivate, onetimePublicKey, publicKey string) (*ristretto.Point, error) { | ||
var a ristretto.Scalar | ||
R := hexToPoint(publicKey) | ||
var aBytes [32]byte | ||
aData, err := hex.DecodeString(viewPrivate) | ||
if err != nil { | ||
return nil, err | ||
} | ||
copy(aBytes[:], aData) | ||
|
||
// hs | ||
var hsp ristretto.Point | ||
var hs ristretto.Scalar | ||
hash := blake2b.New512() | ||
hash.Write([]byte(HASH_TO_SCALAR_DOMAIN_TAG)) | ||
hash.Write(hsp.ScalarMult(R, a.SetBytes(&aBytes)).Bytes()) | ||
var key [64]byte | ||
copy(key[:], hash.Sum(nil)) | ||
|
||
// p | ||
p := hexToPoint(onetimePublicKey) | ||
|
||
var g ristretto.Point | ||
var r1, r ristretto.Point | ||
return r.Sub(p, r1.ScalarMult(g.SetBase(), hs.SetReduced(&key))), nil | ||
} |