Пример #1
0
// GenerateKeyPair returns a private/public key pair.  The private key is
// generated using the given reader, which must return random data.  The
// receiver side of the key exchange (aka "Bob") MUST use KeyExchangeBob()
// instead of this routine.
func GenerateKeyPair(rand io.Reader) (*PrivateKeyAlice, *PublicKeyAlice, error) {
	var a, e, pk, r poly
	var seed, noiseSeed [SeedBytes]byte

	// seed <- Sample({0, 1}^256)
	if _, err := io.ReadFull(rand, seed[:]); err != nil {
		return nil, nil, err
	}
	seed = sha3.Sum256(seed[:]) // Don't send output of system RNG.
	// a <- Parse(SHAKE-128(seed))
	a.uniform(&seed, TorSampling)

	// s, e <- Sample(psi(n, 12))
	if _, err := io.ReadFull(rand, noiseSeed[:]); err != nil {
		return nil, nil, err
	}
	defer memwipe(noiseSeed[:])
	privKey := new(PrivateKeyAlice)
	privKey.sk.getNoise(&noiseSeed, 0)
	privKey.sk.ntt()
	e.getNoise(&noiseSeed, 1)
	e.ntt()

	// b <- as + e
	pubKey := new(PublicKeyAlice)
	r.pointwise(&privKey.sk, &a)
	pk.add(&e, &r)
	encodeA(pubKey.Send[:], &pk, &seed)

	return privKey, pubKey, nil
}
Пример #2
0
func (v *Verifier) VerifySpace(challenges []int64, hashes [][]byte, parents [][][]byte, proofs [][][]byte, pProofs [][][][]byte) bool {
	for i := range challenges {
		buf := make([]byte, hashSize)
		binary.PutVarint(buf, challenges[i]+v.pow2)
		val := append(v.pk, buf...)
		for _, ph := range parents[i] {
			val = append(val, ph...)
		}
		exp := sha3.Sum256(val)
		for j := range exp {
			if exp[j] != hashes[i][j] {
				return false
			}
		}
		if !v.Verify(challenges[i], hashes[i], proofs[i]) {
			return false
		}

		ps := v.graph.GetParents(challenges[i], v.index)
		for j := range ps {
			if !v.Verify(ps[j], parents[i][j], pProofs[i][j]) {
				return false
			}
		}
	}
	return true
}
Пример #3
0
// Iterative function to generate merkle tree
// Should have at most O(lgn) hashes in memory at a time
// return: the root hash
func (p *Prover) generateMerkle() []byte {
	var stack []int64
	var hashStack [][]byte

	cur := int64(1)
	count := int64(1)

	for count == 1 || len(stack) != 0 {
		empty := p.emptyMerkle(cur)
		for ; cur < 2*p.pow2 && !empty; cur *= 2 {
			if cur < p.pow2 { //right child
				stack = append(stack, 2*cur+1)
			}
			stack = append(stack, cur)
		}

		if empty {
			count += p.graph.subtree(cur)
			hashStack = append(hashStack, make([]byte, hashSize))
		}

		cur, stack = stack[len(stack)-1], stack[:len(stack)-1]

		if len(stack) > 0 && cur < p.pow2 &&
			(stack[len(stack)-1] == 2*cur+1) {
			stack = stack[:len(stack)-1]
			stack = append(stack, cur)
			cur = 2*cur + 1
			continue
		}

		if cur >= p.pow2 {
			if cur >= p.pow2+p.size {
				hashStack = append(hashStack, make([]byte, hashSize))
				count++
			} else {
				n := p.graph.GetId(count)
				count++
				hashStack = append(hashStack, n.H)
			}
		} else if !p.emptyMerkle(cur) {
			hash2 := hashStack[len(hashStack)-1]
			hashStack = hashStack[:len(hashStack)-1]
			hash1 := hashStack[len(hashStack)-1]
			hashStack = hashStack[:len(hashStack)-1]
			val := append(hash1[:], hash2[:]...)
			hash := sha3.Sum256(val)

			hashStack = append(hashStack, hash[:])

			p.graph.NewNodeById(count, hash[:])
			count++
		}
		cur = 2 * p.pow2
	}

	return hashStack[0]
}
Пример #4
0
// Compute quality of the answer. Also builds a verifier
// return: quality in float64
func (c *Client) Quality(challenge []byte, a block.Answer) float64 {
	nodes := c.verifier.SelectChallenges(challenge)
	if !c.verifier.VerifySpace(nodes, a.Hashes, a.Parents, a.Proofs, a.PProofs) {
		return -1
	}

	all := util.Concat(a.Hashes)
	answerHash := sha3.Sum256(all)
	x := new(big.Float).SetInt(new(big.Int).SetBytes(answerHash[:]))
	num, _ := util.Root(x, a.Size).Float64()
	den := math.Exp2(float64(1<<8) / float64(a.Size))
	return num / den
}
Пример #5
0
// KeyExchangeBob is the Responder side of the Ring-LWE key exchange.  The
// shared secret and "public key" (key + reconciliation data) are generated
// using the given reader, which must return random data.
func KeyExchangeBob(rand io.Reader, alicePk *PublicKeyAlice) (*PublicKeyBob, []byte, error) {
	var pka, a, sp, ep, u, v, epp, r poly
	var seed, noiseSeed [SeedBytes]byte

	if _, err := io.ReadFull(rand, noiseSeed[:]); err != nil {
		return nil, nil, err
	}
	defer memwipe(noiseSeed[:])

	// a <- Parse(SHAKE-128(seed))
	decodeA(&pka, &seed, alicePk.Send[:])
	a.uniform(&seed, TorSampling)

	// s', e', e'' <- Sample(psi(n, 12))
	sp.getNoise(&noiseSeed, 0)
	sp.ntt()
	ep.getNoise(&noiseSeed, 1)
	ep.ntt()
	epp.getNoise(&noiseSeed, 2)

	// u <- as' + e'
	u.pointwise(&a, &sp)
	u.add(&u, &ep)

	// v <- bs' + e''
	v.pointwise(&pka, &sp)
	v.invNtt()
	v.add(&v, &epp)

	// r <- Sample(HelpRec(v))
	r.helpRec(&v, &noiseSeed, 3)

	pubKey := new(PublicKeyBob)
	encodeB(pubKey.Send[:], &u, &r)

	// nu <- Rec(v, r)
	var nu [SharedSecretSize]byte
	rec(&nu, &v, &r)

	// mu <- SHA3-256(nu)
	mu := sha3.Sum256(nu[:])

	// Scrub the sensitive stuff...
	memwipe(nu[:])
	sp.reset()
	v.reset()

	return pubKey, mu[:], nil
}
Пример #6
0
// Generate challenge from older blocks
// return: challenge for next block []byte
func (c *Client) GenerateChallenge() []byte {
	var b *block.Block
	var err error
	if c.chain.LastBlock < c.dist {
		b, err = c.chain.Read(c.chain.LastBlock)
	} else {
		b, err = c.chain.Read(c.chain.LastBlock - (c.dist - 1))
	}
	if err != nil {
		panic(err)
	}
	bin, err := b.MarshalBinary()
	if err != nil {
		panic(err)
	}
	challenge := sha3.Sum256(bin)
	return challenge[:]
}
Пример #7
0
func NewBlock(old *Block, prf PoS, ts []Transaction, signer crypto.Signer) *Block {
	oldH, err := old.Hash.MarshalBinary()
	if err != nil {
		panic(err)
	}
	prevHash := sha3.Sum256(oldH)
	h := Hash{
		Hash:  prevHash[:],
		Proof: prf,
	}

	var tsBytes []byte
	for i := range ts {
		b, err := ts[i].MarshalBinary()
		if err != nil {
			panic(err)
		}
		tsBytes = append(tsBytes, b...)
	}
	sigBytes := util.Concat([][]byte{old.Sig.Tsig, old.Sig.Ssig})

	tsig, err := signer.Sign(rand.Reader, tsBytes, crypto.SHA3_256)
	if err != nil {
		panic(err)
	}
	ssig, err := signer.Sign(rand.Reader, sigBytes, crypto.SHA3_256)
	if err != nil {
		panic(err)
	}
	sig := Signature{
		Tsig: tsig,
		Ssig: ssig,
	}

	b := Block{
		Id:    old.Id + 1,
		Hash:  h,
		Trans: ts,
		Sig:   sig,
	}
	return &b
}
Пример #8
0
func (v *Verifier) Verify(node int64, hash []byte, proof [][]byte) bool {
	curHash := hash
	counter := 0
	for i := node + v.pow2; i > 1; i /= 2 {
		var val []byte
		if i%2 == 0 {
			val = append(curHash, proof[counter]...)
		} else {
			val = append(proof[counter], curHash...)
		}
		hash := sha3.Sum256(val)
		curHash = hash[:]
		counter++
	}
	for i := range v.root {
		if v.root[i] != curHash[i] {
			return false
		}
	}

	return len(v.root) == len(curHash)
}
Пример #9
0
// KeyExchangeAlice is the Initiaitor side of the Ring-LWE key exchange.  The
// provided private key is obliterated prior to returning, to promote
// implementing Perfect Forward Secrecy.
func KeyExchangeAlice(bobPk *PublicKeyBob, aliceSk *PrivateKeyAlice) ([]byte, error) {
	var u, r, vp poly

	decodeB(&u, &r, bobPk.Send[:])

	// v' <- us
	vp.pointwise(&aliceSk.sk, &u)
	vp.invNtt()

	// nu <- Rec(v', r)
	var nu [SharedSecretSize]byte
	rec(&nu, &vp, &r)

	// mu <- Sha3-256(nu)
	mu := sha3.Sum256(nu[:])

	// Scrub the sensitive stuff...
	memwipe(nu[:])
	vp.reset()
	aliceSk.Reset()

	return mu[:], nil
}
Пример #10
0
func (g *Graph) ButterflyGraph(index int64, count *int64) {
	if index == 0 {
		index = 1
	}
	numLevel := 2 * index
	perLevel := int64(1 << uint64(index))
	begin := *count - perLevel // level 0 created outside
	// no parents at level 0
	var level, i int64
	for level = 1; level < numLevel; level++ {
		for i = 0; i < perLevel; i++ {
			var prev int64
			shift := index - level
			if level > numLevel/2 {
				shift = level - numLevel/2
			}
			if (i>>uint64(shift))&1 == 0 {
				prev = i + (1 << uint64(shift))
			} else {
				prev = i - (1 << uint64(shift))
			}
			parent0 := g.GetNode(begin + (level-1)*perLevel + prev)
			parent1 := g.GetNode(*count - perLevel)

			ph := append(parent0.H, parent1.H...)
			buf := make([]byte, hashSize)
			binary.PutVarint(buf, *count)
			val := append(g.pk, buf...)
			val = append(val, ph...)
			hash := sha3.Sum256(val)

			g.NewNode(*count, hash[:])
			*count++
		}
	}
}
// hash_string hashes a string
func hash_string(key string) string {
	hash := sha3.Sum256([]byte(key))
	return base64.StdEncoding.EncodeToString(hash[:])
}
Пример #12
0
func (g *Graph) XiGraph(index int64, count *int64) {
	// recursively generate graphs
	// compute hashes along the way

	pow2index := int64(1 << uint64(index))

	// the first sources
	// if index == 1, then this will generate level 0 of the butterfly
	var i int64

	if *count == g.pow2 {
		for i = 0; i < pow2index; i++ {
			buf := make([]byte, hashSize)
			binary.PutVarint(buf, *count)
			val := append(g.pk, buf...)
			hash := sha3.Sum256(val)

			g.NewNode(*count, hash[:])
			*count++
		}
	}

	if index == 1 {
		g.ButterflyGraph(index, count)
		return
	}

	sources := *count - pow2index
	firstButter := sources + pow2index
	firstXi := firstButter + numButterfly(index-1)
	secondXi := firstXi + numXi(index-1)
	secondButter := secondXi + numXi(index-1)
	sinks := secondButter + numButterfly(index-1)
	pow2index_1 := int64(1 << uint64(index-1))

	// sources to sources of first butterfly
	// create sources of first butterly
	for i = 0; i < pow2index_1; i++ {
		parent0 := g.GetNode(sources + i)
		parent1 := g.GetNode(sources + i + pow2index_1)

		ph := append(parent0.H, parent1.H...)
		buf := make([]byte, hashSize)
		binary.PutVarint(buf, *count)
		val := append(g.pk, buf...)
		val = append(val, ph...)
		hash := sha3.Sum256(val)

		g.NewNode(*count, hash[:])
		*count++
	}

	g.ButterflyGraph(index-1, count)
	// sinks of first butterfly to sources of first xi graph
	for i = 0; i < pow2index_1; i++ {
		nodeId := firstXi + i
		parent := g.GetNode(firstXi - pow2index_1 + i)

		buf := make([]byte, hashSize)
		binary.PutVarint(buf, nodeId)
		val := append(g.pk, buf...)
		val = append(val, parent.H...)
		hash := sha3.Sum256(val)

		g.NewNode(nodeId, hash[:])
		*count++
	}

	g.XiGraph(index-1, count)
	// sinks of first xi to sources of second xi
	for i = 0; i < pow2index_1; i++ {
		nodeId := secondXi + i
		parent := g.GetNode(secondXi - pow2index_1 + i)

		buf := make([]byte, hashSize)
		binary.PutVarint(buf, nodeId)
		val := append(g.pk, buf...)
		val = append(val, parent.H...)
		hash := sha3.Sum256(val)

		g.NewNode(nodeId, hash[:])
		*count++
	}

	g.XiGraph(index-1, count)
	// sinks of second xi to sources of second butterfly
	for i = 0; i < pow2index_1; i++ {
		nodeId := secondButter + i
		parent := g.GetNode(secondButter - pow2index_1 + i)

		buf := make([]byte, hashSize)
		binary.PutVarint(buf, nodeId)
		val := append(g.pk, buf...)
		val = append(val, parent.H...)
		hash := sha3.Sum256(val)

		g.NewNode(nodeId, hash[:])
		*count++
	}

	// generate sinks
	// sinks of second butterfly to sinks
	// and sources to sinks directly
	g.ButterflyGraph(index-1, count)
	for i = 0; i < pow2index_1; i++ {
		nodeId0 := sinks + i
		nodeId1 := sinks + i + pow2index_1
		parent0 := g.GetNode(sinks - pow2index_1 + i)
		parent1_0 := g.GetNode(sources + i)
		parent1_1 := g.GetNode(sources + i + pow2index_1)

		ph := append(parent0.H, parent1_0.H...)
		buf := make([]byte, hashSize)
		binary.PutVarint(buf, nodeId0)
		val := append(g.pk, buf...)
		val = append(val, ph...)
		hash1 := sha3.Sum256(val)

		ph = append(parent0.H, parent1_1.H...)
		binary.PutVarint(buf, nodeId1)
		val = append(g.pk, buf...)
		val = append(val, ph...)
		hash2 := sha3.Sum256(val)

		g.NewNode(nodeId0, hash1[:])
		g.NewNode(nodeId1, hash2[:])
		*count += 2
	}
}
Пример #13
0
// Iterative generation of the graph
func (g *Graph) XiGraphIter(index int64) {
	count := g.pow2

	stack := []int64{index, index, index, index, index}
	graphStack := []int{4, 3, 2, 1, 0}

	var i int64
	graph := 0
	pow2index := int64(1 << uint64(index))
	for i = 0; i < pow2index; i++ { //sources at this level
		buf := make([]byte, hashSize)
		binary.PutVarint(buf, count)
		val := append(g.pk, buf...)
		hash := sha3.Sum256(val)

		g.NewNode(count, hash[:])
		count++
	}

	if index == 1 {
		g.ButterflyGraph(index, &count)
		return
	}

	for len(stack) != 0 && len(graphStack) != 0 {
		index, stack = stack[len(stack)-1], stack[:len(stack)-1]
		graph, graphStack = graphStack[len(graphStack)-1], graphStack[:len(graphStack)-1]

		indices := []int64{index - 1, index - 1, index - 1, index - 1, index - 1}
		graphs := []int{4, 3, 2, 1, 0}

		pow2index := int64(1 << uint64(index))
		pow2index_1 := int64(1 << uint64(index-1))

		if graph == 0 {
			sources := count - pow2index
			// sources to sources of first butterfly
			// create sources of first butterly
			for i = 0; i < pow2index_1; i++ {
				parent0 := g.GetNode(sources + i)
				parent1 := g.GetNode(sources + i + pow2index_1)

				ph := append(parent0.H, parent1.H...)
				buf := make([]byte, hashSize)
				binary.PutVarint(buf, count)
				val := append(g.pk, buf...)
				val = append(val, ph...)
				hash := sha3.Sum256(val)

				g.NewNode(count, hash[:])
				count++
			}
		} else if graph == 1 {
			firstXi := count
			// sinks of first butterfly to sources of first xi graph
			for i = 0; i < pow2index_1; i++ {
				nodeId := firstXi + i
				// index is the last level; i.e., sinks
				parent := g.GetNode(firstXi - pow2index_1 + i)

				buf := make([]byte, hashSize)
				binary.PutVarint(buf, nodeId)
				val := append(g.pk, buf...)
				val = append(val, parent.H...)
				hash := sha3.Sum256(val)

				g.NewNode(nodeId, hash[:])
				count++
			}
		} else if graph == 2 {
			secondXi := count
			// sinks of first xi to sources of second xi
			for i = 0; i < pow2index_1; i++ {
				nodeId := secondXi + i
				parent := g.GetNode(secondXi - pow2index_1 + i)

				buf := make([]byte, hashSize)
				binary.PutVarint(buf, nodeId)
				val := append(g.pk, buf...)
				val = append(val, parent.H...)
				hash := sha3.Sum256(val)

				g.NewNode(nodeId, hash[:])
				count++
			}
		} else if graph == 3 {
			secondButter := count
			// sinks of second xi to sources of second butterfly
			for i = 0; i < pow2index_1; i++ {
				nodeId := secondButter + i
				parent := g.GetNode(secondButter - pow2index_1 + i)

				buf := make([]byte, hashSize)
				binary.PutVarint(buf, nodeId)
				val := append(g.pk, buf...)
				val = append(val, parent.H...)
				hash := sha3.Sum256(val)

				g.NewNode(nodeId, hash[:])
				count++
			}
		} else {
			sinks := count
			sources := sinks + pow2index - numXi(index)
			for i = 0; i < pow2index_1; i++ {
				nodeId0 := sinks + i
				nodeId1 := sinks + i + pow2index_1
				parent0 := g.GetNode(sinks - pow2index_1 + i)
				parent1_0 := g.GetNode(sources + i)
				parent1_1 := g.GetNode(sources + i + pow2index_1)

				ph := append(parent0.H, parent1_0.H...)
				buf := make([]byte, hashSize)
				binary.PutVarint(buf, nodeId0)
				val := append(g.pk, buf...)
				val = append(val, ph...)
				hash1 := sha3.Sum256(val)

				ph = append(parent0.H, parent1_1.H...)
				binary.PutVarint(buf, nodeId1)
				val = append(g.pk, buf...)
				val = append(val, ph...)
				hash2 := sha3.Sum256(val)

				g.NewNode(nodeId0, hash1[:])
				g.NewNode(nodeId1, hash2[:])
				count += 2
			}
		}

		if (graph == 0 || graph == 3) ||
			((graph == 1 || graph == 2) && index == 2) {
			g.ButterflyGraph(index-1, &count)
		} else if graph == 1 || graph == 2 {
			stack = append(stack, indices...)
			graphStack = append(graphStack, graphs...)
		}
	}
}
Пример #14
0
func Sum256(password string) string {
	buf := []byte(password)
	hash := sha3.Sum256(buf)
	return string(hash[:])
}