github.com/quantosnetwork/Quantos@v0.0.0-20220306172517-e20b28c5a29a/uint512/uint512.go (about)

     1  package uint512
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/sha256"
     6  	"encoding/hex"
     7  	"github.com/holiman/uint256"
     8  	"github.com/quantosnetwork/Quantos/crypto"
     9  	"github.com/zeebo/blake3"
    10  	"go.dedis.ch/kyber/v3"
    11  	"go.dedis.ch/kyber/v3/group/edwards25519"
    12  	"go.dedis.ch/kyber/v3/sign/schnorr"
    13  	"lukechampine.com/frand"
    14  	"math/big"
    15  	"time"
    16  )
    17  
    18  type Uint512 struct {
    19  	a, b *uint256.Int
    20  }
    21  
    22  type Int struct {
    23  	b []byte
    24  }
    25  
    26  func NewUint512FromBytes(a1, b1 []byte) *Uint512 {
    27  
    28  	ab1 := ToBigInt(a1)
    29  	ab2 := ToBigInt(b1)
    30  	u1, _ := uint256.FromBig(ab1)
    31  	u2, _ := uint256.FromBig(ab2)
    32  	return &Uint512{
    33  		u1, u2,
    34  	}
    35  }
    36  
    37  func ToBigInt(bb []byte) *big.Int {
    38  
    39  	bbb := new(big.Int)
    40  	bbb.SetBytes(bb)
    41  	return bbb
    42  
    43  }
    44  
    45  func (u512 *Uint512) Mul(a, b *uint256.Int) (r0, r1 *uint256.Int) {
    46  	mmu := uint256.NewInt(0)
    47  	mm := mmu.MulMod(a, b, uint256.NewInt(1))
    48  	r0 = mmu.Mul(a, b)
    49  	r1 = mmu.Sub(mm, r0)
    50  	r0.Lt(mm)
    51  	return
    52  }
    53  
    54  func (u512 *Uint512) Merge() *Int {
    55  	buf := make([][]byte, 2)
    56  	buf[0] = u512.a.Bytes()
    57  	buf[1] = u512.b.Bytes()
    58  	nInt := bytes.Join(buf, nil)
    59  	var bufInt Int
    60  	copy(bufInt.b, nInt[:])
    61  	return &bufInt
    62  }
    63  
    64  func (uInt *Int) ToUint512Struct() *Uint512 {
    65  
    66  	a := uInt.Bytes()[0:255]
    67  	b := uInt.Bytes()[255:]
    68  	bb := new(big.Int).SetBytes(a[:])
    69  	ba := new(big.Int).SetBytes(b[:])
    70  	bba, _ := uint256.FromBig(bb)
    71  	bbb, _ := uint256.FromBig(ba)
    72  	return &Uint512{bba, bbb}
    73  
    74  }
    75  
    76  func NewIntFromUint64s(a, b uint64) (*Uint512, *Int) {
    77  
    78  	aa := uint256.NewInt(a)
    79  	bb := uint256.NewInt(b)
    80  	_uint := &Uint512{aa, bb}
    81  	return _uint, _uint.Merge()
    82  
    83  }
    84  
    85  func NewBlankUint512() (*Uint512, *Int) {
    86  	aa := uint256.NewInt(0)
    87  	bb := uint256.NewInt(0)
    88  	_uint := &Uint512{aa, bb}
    89  	return _uint, _uint.Merge()
    90  
    91  }
    92  
    93  func (u512 *Uint512) FromBig(a, b *big.Int) *Int {
    94  	aa, _ := uint256.FromBig(a)
    95  	bb, _ := uint256.FromBig(b)
    96  	_uint := &Uint512{aa, bb}
    97  	return _uint.Merge()
    98  }
    99  
   100  func (uInt *Int) ToHex() string {
   101  
   102  	return hex.EncodeToString(uInt.Bytes())
   103  
   104  }
   105  
   106  func (uInt *Int) ToString() string {
   107  	return "0x" + uInt.ToHex()
   108  }
   109  
   110  func (uInt *Int) Bytes() []byte {
   111  	return uInt.b
   112  }
   113  
   114  func (uInt *Int) Hash() []byte {
   115  	hasher := blake3.Hasher{}
   116  	hasher.Write(uInt.Bytes()[:])
   117  	sum := hasher.Sum(nil)
   118  	return sum
   119  }
   120  
   121  func (uInt *Int) KeyedSignedHash(key kyber.Scalar) (hash []byte, sig []byte) {
   122  
   123  	// to make a key we take the sha256 of the private key (kyber.Scalar)
   124  	k, _ := key.MarshalBinary()
   125  	h := sha256.Sum256(k)
   126  	hk, _ := blake3.NewKeyed(h[:])
   127  	hk.Write(uInt.Bytes()[:])
   128  	hash = hk.Sum(nil)
   129  	var suite *edwards25519.SuiteEd25519
   130  	sig, _ = schnorr.Sign(suite, key, hash)
   131  	return
   132  }
   133  
   134  func (uInt *Int) Sign(key kyber.Scalar, msg []byte) []byte {
   135  	var suite *edwards25519.SuiteEd25519
   136  	sig, _ := schnorr.Sign(suite, key, msg)
   137  	return sig
   138  }
   139  
   140  func (uInt *Int) VerifySignedContent(key kyber.Point, msg []byte, sig []byte) bool {
   141  	var group kyber.Group
   142  	err := schnorr.Verify(group, key, msg, sig)
   143  	if err != nil {
   144  		return false
   145  	}
   146  	return true
   147  }
   148  
   149  type address struct {
   150  	*Uint512
   151  }
   152  
   153  type Address struct {
   154  	Raw             *address
   155  	pk              []byte
   156  	sk              []byte
   157  	ssk             []byte
   158  	group           kyber.Group
   159  	suite           *edwards25519.SuiteEd25519
   160  	Signature       []byte
   161  	TimestampSigned []byte
   162  	Timestamp       int64
   163  }
   164  
   165  func (addr *address) Create() *Address {
   166  	seed := make([]byte, 512)
   167  	frand.Read(seed)
   168  	seedA := seed[:255]
   169  	seedB := seed[255:]
   170  	u := new(Uint512)
   171  	sab := new(big.Int).SetBytes(seedA)
   172  	sbb := new(big.Int).SetBytes(seedB)
   173  	u.a, _ = uint256.FromBig(sab)
   174  	u.b, _ = uint256.FromBig(sbb)
   175  	add := new(Address)
   176  	add.Raw = &address{u}
   177  
   178  	k := crypto.GenerateHardenedKeys()
   179  	add.pk, _ = k.PubKey.MarshalBinary()
   180  	add.sk, _ = k.PrivKey.MarshalBinary()
   181  	add.group = k.Group
   182  	add.suite = k.Suite
   183  	_ = k.PrivKey.UnmarshalBinary(add.sk)
   184  
   185  	// we sign the public key
   186  	now := time.Now().UnixNano()
   187  	pubbytes, _ := k.PubKey.MarshalBinary()
   188  	add.Signature = k.Sign(pubbytes)
   189  	n256 := uint256.NewInt(uint64(now))
   190  	add.TimestampSigned = k.Sign(n256.Bytes())
   191  	add.Timestamp = now
   192  	return add
   193  }
   194  
   195  func (addr *Address) Serialize() []byte {
   196  
   197  	toSerialize := addr.Raw.a.String() + "-" + hex.EncodeToString(addr.pk) + "-" + hex.EncodeToString(addr.
   198  		Signature) + "-" + hex.
   199  		EncodeToString(addr.TimestampSigned)
   200  	return []byte(toSerialize)
   201  }
   202  
   203  func (addr *Address) Master() []byte {
   204  	privateKey := addr.sk
   205  	keyed, _ := blake3.NewKeyed(privateKey)
   206  	keyed.Write(addr.Serialize())
   207  	return keyed.Sum(nil)
   208  
   209  }
   210  
   211  func (addr *Address) Derive() string {
   212  	buf := make([]byte, 32)
   213  	frand.Read(buf)
   214  	bb := new(big.Int).SetBytes(buf).String()
   215  	walletBytes := make([]byte, 40)
   216  	blake3.DeriveKey("qbit-address-"+bb, addr.Serialize(), walletBytes)
   217  	wbb := new(big.Int).SetBytes(walletBytes)
   218  	u, _ := uint256.FromBig(wbb)
   219  	return u.String()
   220  }