Skip to content

Commit

Permalink
Base 0 commit
Browse files Browse the repository at this point in the history
  • Loading branch information
raghu0891 committed Nov 26, 2024
0 parents commit 6d268d8
Show file tree
Hide file tree
Showing 101 changed files with 58,728 additions and 0 deletions.
33 changes: 33 additions & 0 deletions altbn_128/bn256_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package altbn_128

import (
"math/big"

bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
)

type g1Interface interface {
String() string
ScalarBaseMult(k *big.Int) *bn256.G1
ScalarMult(a *bn256.G1, k *big.Int) *bn256.G1
Add(a, b *bn256.G1) *bn256.G1
Neg(a *bn256.G1) *bn256.G1
Set(a *bn256.G1) *bn256.G1
Marshal() []byte
Unmarshal(m []byte) ([]byte, error)
}

var _ g1Interface = (*bn256.G1)(nil)

type g2Interface interface {
String() string
ScalarBaseMult(k *big.Int) *bn256.G2
ScalarMult(a *bn256.G2, k *big.Int) *bn256.G2
Add(a, b *bn256.G2) *bn256.G2
Neg(a *bn256.G2) *bn256.G2
Set(a *bn256.G2) *bn256.G2
Marshal() []byte
Unmarshal(m []byte) ([]byte, error)
}

var _ g2Interface = (*bn256.G2)(nil)
67 changes: 67 additions & 0 deletions altbn_128/g1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package altbn_128

import (
"crypto/cipher"
"math/big"

"go.dedis.ch/kyber/v3"
"go.dedis.ch/kyber/v3/sign/anon"

bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"

"github.com/goplugin/plugin-vrf/altbn_128/scalar"
)

type G1 struct{ r cipher.Stream }

var _ kyber.Group = (*G1)(nil)
var _ anon.Suite = (*G1)(nil)

func newG1() *G1 {
return &G1{}
}

func (g *G1) String() string {
return "AltBN-128 G₁"
}

func (g *G1) ScalarLen() int {
return g1ScalarLength
}

func (g *G1) Scalar() kyber.Scalar {
return scalar.NewScalarInt64(0)
}

func (g *G1) PointLen() int {
return g1PointLength
}

func (g *G1) Point() kyber.Point {
return newG1Point()
}

var g1ScalarLength, g1PointLength int
var zero, one *big.Int
var null, g1Base *g1Point

func init() {
zero, one = big.NewInt(0), big.NewInt(1)

b, err := new(G1).Scalar().Zero().MarshalBinary()
if err != nil {
panic(err)
}
g1ScalarLength = len(b)

rawG1Base := new(bn256.G1).ScalarBaseMult(one)
g1Base = &g1Point{rawG1Base}
negG1Base := new(bn256.G1).Neg(rawG1Base)
g1Null := new(bn256.G1).Add(rawG1Base, negG1Base)
null = &g1Point{g1Null}
b, err = null.MarshalBinary()
if err != nil {
panic(err)
}
g1PointLength = len(b)
}
247 changes: 247 additions & 0 deletions altbn_128/g1_hash_to_curve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
package altbn_128

import (
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"

"github.com/goplugin/plugin-vrf/gethwrappers/vrf"
"github.com/goplugin/plugin-vrf/internal/util"

bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"

"go.dedis.ch/kyber/v3"
"go.dedis.ch/kyber/v3/group/mod"
)

var (
curve = (&PairingSuite{}).G1()
p = bn256.P
curveB = m(3)

j = big.NewInt
uint256Bound = j(0).Lsh(j(1), 256)
uint256ModP = j(0).Mod(uint256Bound, p)
maxP = j(0).Sub(uint256Bound, uint256ModP)

sqrMinus3, sqrMinus3Valid = m(0), sqrMinus3.Sqrt(m(-3))
thirdModP = m(0).Exp(m(3), j(-1))
sqrpwr = j(0).Rsh(j(0).Add(p, j(1)), 2)

vConst, _ = m(0), vConst.Div(vConst.Add(m(-1), sqrMinus3), m(2))
)

type fProof struct {
point kyber.Point
t *big.Int
interimValues vrf.HashToCurveFProof
}

var zeroHashPoint = hexutil.MustDecode(
"0x000000000000000059e26bcea0d48bacd4f263f1acdb5c4f5763473177fffffe",
)

func newFProof(t *big.Int) *fProof {
if t.Cmp(j(0)) == 0 {
return &fProof{point: curve.Point().Null(), t: t}
}
if t.Cmp(maxP) >= 0 {

panic("input must be less than maxP")
}
it := mod.NewInt(t, p)
tmp := m(0)
iTSquared := m(0).Mul(it, it)
denom := tmp.Add(m(1), tmp.Add(curveB, iTSquared))
denomInv := m(0).Inv(denom)
tmp = m(0)
v := tmp.Sub(vConst, tmp.Mul(tmp.Mul(sqrMinus3, iTSquared), denomInv))
pseudoSqrtY := func(x *mod.Int) (isActualSquareRoot bool, psqrt *mod.Int) {
tmp := m(0)
ySquare := tmp.Add(tmp.Mul(tmp.Mul(x, x), x), curveB).(*mod.Int)

pseudoY := m(0).Exp(ySquare, sqrpwr)
pseudoYSquare := m(0).Mul(pseudoY, pseudoY)
valid := pseudoYSquare.Equal(ySquare)
if !valid {
negPseudoYSquare := m(0).Neg(pseudoYSquare)
if !negPseudoYSquare.Equal(ySquare) {
panic(fmt.Sprintln("failed to compute correct pseudo square root of", ySquare))
}
}
return valid, pseudoY.(*mod.Int)
}
rv := &fProof{
t: t,
interimValues: vrf.HashToCurveFProof{
DenomInv: &denomInv.(*mod.Int).V,

TInvSquared: j(0), Y1: j(0), Y2: j(0), Y3: j(0),
},
}

x1 := v.Clone().(*mod.Int)
valid, y1 := pseudoSqrtY(x1)
rv.interimValues.Y1 = &y1.V
if valid {
rv.point = coordinatesToG1(x1, y1, it)
return rv
}

x2 := m(0).Neg(m(0).Add(x1, m(1))).(*mod.Int)
valid, y2 := pseudoSqrtY(x2)
rv.interimValues.Y2 = &y2.V
if valid {
rv.point = coordinatesToG1(x2, y2, it)
return rv
}

tInvSquared := m(0).Exp(it, j(-2)).(*mod.Int)
numSquared := m(0).Mul(denom, denom)
x3 := m(0).Sub(m(1), m(0).Mul(numSquared, m(0).Mul(tInvSquared, thirdModP))).(*mod.Int)
valid, y3 := pseudoSqrtY(x3)
rv.interimValues.Y3 = &y3.V
rv.interimValues.TInvSquared = &tInvSquared.V
if valid {
rv.point = coordinatesToG1(x3, y3, it)
return rv
}

panic(
"one of x1, x2, x3 should have been the x ordinate of a point on G1: " +
rv.String(),
)
}

func coordinatesToG1(x, y, t *mod.Int) *g1Point {
if x.M.Cmp(p) != 0 || y.M.Cmp(p) != 0 || t.M.Cmp(p) != 0 {
panic("inputs are not in base field")
}
xBin, err := x.MarshalBinary()
if err != nil {
panic(err)
}
targetParity := t.V.Bit(0)
if y.V.Bit(0) != targetParity {
_ = y.Neg(y)
if y.V.Bit(0) != targetParity {
panic("failed to set target parity for output")
}
}
yBin, err := y.MarshalBinary()
if err != nil {
panic(err)
}
pt := newG1Point()
if _, err := pt.G1.Unmarshal(append(xBin, yBin...)); err != nil {
panic(err)
}
return pt
}

func CoordinatesToG1(x, y *mod.Int) (kyber.Point, error) {
if x.M.Cmp(p) != 0 {
return nil, fmt.Errorf("x ordinate %+v is not in base field", x)
}
if y.M.Cmp(p) != 0 {
return nil, fmt.Errorf("y ordinate %+v is not in base field", y)
}
xBin, err := x.MarshalBinary()
if err != nil {
return nil, util.WrapError(err, "could not marshal x ordinate")
}
yBin, err := y.MarshalBinary()
if err != nil {
return nil, util.WrapError(err, "could not marshal y ordinate")
}
pt := newG1Point()
combinedOrdinates := append(xBin, yBin...)
if _, err := pt.G1.Unmarshal(combinedOrdinates); err != nil {
return nil, util.WrapErrorf(
err,
"could not unmarshal combined ordinates 0x%x",
combinedOrdinates,
)
}
return pt, nil
}

type HashProof struct {
msg [32]byte
HashPoint kyber.Point
SummandProofs [2]*fProof
}

func NewHashProof(msg [32]byte) *HashProof {
rv := &HashProof{msg: msg, HashPoint: newG1Point().Null()}
for hashCount := 0; hashCount < 2; {
nmsg := crypto.Keccak256(msg[:])
copy(msg[:], nmsg)
t := j(0).SetBytes(msg[:])
if t.Cmp(maxP) < 0 {
t = t.Mod(t, p)
rv.SummandProofs[hashCount] = newFProof(t)
rv.HashPoint = newG1Point().Add(rv.HashPoint, rv.SummandProofs[hashCount].point)
hashCount++
}
}
return rv
}

func init() {
if !sqrMinus3Valid {
panic("-3 is not a square in ℤ/pℤ")
}
if j(0).Lsh(sqrpwr, 2).Cmp(j(0).Add(p, j(1))) != 0 {
panic("p ≢ 3 mod 4")
}
}

func SolidityVRFProof(pubKey, output kyber.Point, hp HashProof) (*vrf.VRFProof, error) {
pubKeyB, err := pubKey.MarshalBinary()
if err != nil {
return nil, err
}
var pubKeySol vrf.ECCArithmeticG2Point
for i := range pubKeySol.P {
pubKeySol.P[i] = big.NewInt(0).SetBytes(pubKeyB[i*32 : (i+1)*32])
}
outputB := LongMarshal(output)
var outputSol vrf.ECCArithmeticG1Point
for i := range outputSol.P {
outputSol.P[i] = big.NewInt(0).SetBytes(outputB[i*32 : (i+1)*32])
}
proof := vrf.VRFProof{
pubKeySol,
outputSol,
hp.SummandProofs[0].interimValues,
hp.SummandProofs[1].interimValues,
}
return &proof, nil
}

func (hp *HashProof) EqualFProofs(f1, f2 vrf.HashToCurveFProof) bool {
s := hp.SummandProofs
return f1.DenomInv.Cmp(s[0].interimValues.DenomInv) == 0 &&
f1.TInvSquared.Cmp(s[0].interimValues.TInvSquared) == 0 &&
f1.Y1.Cmp(s[0].interimValues.Y1) == 0 &&
f1.Y2.Cmp(s[0].interimValues.Y2) == 0 &&
f1.Y3.Cmp(s[0].interimValues.Y3) == 0 &&
f2.DenomInv.Cmp(s[1].interimValues.DenomInv) == 0 &&
f2.TInvSquared.Cmp(s[1].interimValues.TInvSquared) == 0 &&
f2.Y1.Cmp(s[1].interimValues.Y1) == 0 &&
f2.Y2.Cmp(s[1].interimValues.Y2) == 0 &&
f2.Y3.Cmp(s[1].interimValues.Y3) == 0
}

func (f *fProof) String() string {
i := f.interimValues
return fmt.Sprintf(
"&fProof{point: %s, t: 0x%x, interimValues: "+
"{DenomInv: 0x%x, TInvSquared: 0x%x, Y1: 0x%x, Y2: 0x%x, Y3: 0x%x}"+
"}",
f.point, f.t, i.DenomInv, i.TInvSquared, i.Y1, i.Y2, i.Y3,
)
}
26 changes: 26 additions & 0 deletions altbn_128/g1_message_incidentals.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package altbn_128

import (
"crypto/cipher"
"io"
"reflect"

"go.dedis.ch/kyber/v3"
"go.dedis.ch/kyber/v3/util/random"
"go.dedis.ch/kyber/v3/xof/blake2xb"
)

func (g *G1) XOF(seed []byte) kyber.XOF {
return blake2xb.New(seed)
}

func (g *G1) RandomStream() cipher.Stream {
if g.r != nil {
return g.r
}
return random.New()
}

func (g *G1) Write(w io.Writer, objs ...interface{}) error { panic("not implemented") }
func (g *G1) Read(r io.Reader, objs ...interface{}) error { panic("not implemented") }
func (g *G1) New(t reflect.Type) interface{} { panic("not implemented") }
Loading

0 comments on commit 6d268d8

Please sign in to comment.