mirror of
				https://source.quilibrium.com/quilibrium/ceremonyclient.git
				synced 2025-11-04 12:17:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			87 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
//
 | 
						|
// Copyright (c) 2019 harmony-one
 | 
						|
//
 | 
						|
// SPDX-License-Identifier: MIT
 | 
						|
//
 | 
						|
 | 
						|
package iqc
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"crypto/sha256"
 | 
						|
	"encoding/binary"
 | 
						|
	"math/big"
 | 
						|
)
 | 
						|
 | 
						|
type Pair struct {
 | 
						|
	p int64
 | 
						|
	q int64
 | 
						|
}
 | 
						|
 | 
						|
var m = 8 * 3 * 5 * 7 * 11 * 13
 | 
						|
 | 
						|
func EntropyFromSeed(seed []byte, byte_count uint32) []byte {
 | 
						|
	buffer := bytes.Buffer{}
 | 
						|
	bufferSize := uint32(0)
 | 
						|
 | 
						|
	extra := uint16(0)
 | 
						|
	bytes := make([]byte, len(seed)+2)
 | 
						|
	copy(bytes, seed)
 | 
						|
	for bufferSize <= byte_count {
 | 
						|
		binary.BigEndian.PutUint16(bytes[len(seed):], extra)
 | 
						|
		more_entropy := sha256.Sum256(bytes)
 | 
						|
		buffer.Write(more_entropy[:])
 | 
						|
		bufferSize += sha256.Size
 | 
						|
		extra += 1
 | 
						|
	}
 | 
						|
 | 
						|
	return buffer.Bytes()[:byte_count]
 | 
						|
}
 | 
						|
 | 
						|
//Return a discriminant of the given length using the given seed
 | 
						|
//It is a random prime p between 13 - 2^2K
 | 
						|
//return -p, where p % 8 == 7
 | 
						|
func CreateDiscriminant(seed []byte, length uint32) *big.Int {
 | 
						|
	extra := uint8(length) & 7
 | 
						|
	byte_count := ((length + 7) >> 3) + 2
 | 
						|
	entropy := EntropyFromSeed(seed, byte_count)
 | 
						|
 | 
						|
	n := new(big.Int)
 | 
						|
	n.SetBytes(entropy[:len(entropy)-2])
 | 
						|
	n = new(big.Int).Rsh(n, uint(((8 - extra) & 7)))
 | 
						|
	n = new(big.Int).SetBit(n, int(length-1), 1)
 | 
						|
	n = new(big.Int).Sub(n, new(big.Int).Mod(n, big.NewInt(int64(m))))
 | 
						|
	n = new(big.Int).Add(n, big.NewInt(int64(residues[int(binary.BigEndian.Uint16(entropy[len(entropy)-2:]))%len(residues)])))
 | 
						|
 | 
						|
	negN := new(big.Int).Neg(n)
 | 
						|
 | 
						|
	// Find the smallest prime >= n of the form n + m*x
 | 
						|
	for {
 | 
						|
		sieve := make([]bool, (1 << 16))
 | 
						|
 | 
						|
		for _, v := range sieve_info {
 | 
						|
			// q = m^-1 (mod p)
 | 
						|
			// i = -n / m, so that m*i is -n (mod p)
 | 
						|
			//i := ((-n % v.p) * v.q) % v.p
 | 
						|
			i := (new(big.Int).Mod(negN, big.NewInt(v.p)).Int64() * v.q) % v.p
 | 
						|
 | 
						|
			for i < int64(len(sieve)) {
 | 
						|
				sieve[i] = true
 | 
						|
				i += v.p
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		for i, v := range sieve {
 | 
						|
			t := new(big.Int).Add(n, big.NewInt(int64(m)*int64(i)))
 | 
						|
			if !v && t.ProbablyPrime(1) {
 | 
						|
				return new(big.Int).Neg(t)
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		//n += m * (1 << 16)
 | 
						|
		bigM := big.NewInt(int64(m))
 | 
						|
		n = new(big.Int).Add(n, bigM.Mul(bigM, big.NewInt(int64(1<<16))))
 | 
						|
 | 
						|
	}
 | 
						|
}
 |