Do not export internal threshold generator functions
This commit is contained in:
2 files changed
+54
-54
No files matched your search
+34
-34
@@ -57,23 +57,23 @@ func GetThresholdKeyGenerator(nbits, TotalNumberOfDecryptionServers, Threshold i
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) GenerateSafePrimes() (*big.Int, *big.Int, error) {
|
func (this *ThresholdKeyGenerator) generateSafePrimes() (*big.Int, *big.Int, error) {
|
||||||
return GenerateSafePrimes(this.nbits, this.Random)
|
return GenerateSafePrimes(this.nbits, this.Random)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) InitPandP1() error {
|
func (this *ThresholdKeyGenerator) initPandP1() error {
|
||||||
var err error
|
var err error
|
||||||
this.p, this.p1, err = this.GenerateSafePrimes()
|
this.p, this.p1, err = this.generateSafePrimes()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) InitQandQ1() error {
|
func (this *ThresholdKeyGenerator) initQandQ1() error {
|
||||||
var err error
|
var err error
|
||||||
this.q, this.q1, err = this.GenerateSafePrimes()
|
this.q, this.q1, err = this.generateSafePrimes()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) InitShortcuts() {
|
func (this *ThresholdKeyGenerator) initShortcuts() {
|
||||||
this.n = new(big.Int).Mul(this.p, this.q)
|
this.n = new(big.Int).Mul(this.p, this.q)
|
||||||
this.m = new(big.Int).Mul(this.p1, this.q1)
|
this.m = new(big.Int).Mul(this.p1, this.q1)
|
||||||
this.nSquare = new(big.Int).Mul(this.n, this.n)
|
this.nSquare = new(big.Int).Mul(this.n, this.n)
|
||||||
@@ -81,7 +81,7 @@ func (this *ThresholdKeyGenerator) InitShortcuts() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) ArePsAndQsGood() bool {
|
func (this *ThresholdKeyGenerator) arePsAndQsGood() bool {
|
||||||
if this.p.Cmp(this.q) == 0 {
|
if this.p.Cmp(this.q) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -94,21 +94,21 @@ func (this *ThresholdKeyGenerator) ArePsAndQsGood() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) InitPsAndQs() error {
|
func (this *ThresholdKeyGenerator) initPsAndQs() error {
|
||||||
if err := this.InitPandP1(); err != nil {
|
if err := this.initPandP1(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := this.InitQandQ1(); err != nil {
|
if err := this.initQandQ1(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !this.ArePsAndQsGood() {
|
if !this.arePsAndQsGood() {
|
||||||
return this.InitPsAndQs()
|
return this.initPsAndQs()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// v generates a cyclic group of squares in Zn^2.
|
// v generates a cyclic group of squares in Zn^2.
|
||||||
func (this *ThresholdKeyGenerator) ComputeV() error {
|
func (this *ThresholdKeyGenerator) computeV() error {
|
||||||
var err error
|
var err error
|
||||||
this.v, err = GetRandomGeneratorOfTheQuadraticResidue(this.nSquare, this.Random)
|
this.v, err = GetRandomGeneratorOfTheQuadraticResidue(this.nSquare, this.Random)
|
||||||
return err
|
return err
|
||||||
@@ -138,18 +138,18 @@ func (this *ThresholdKeyGenerator) ComputeV() error {
|
|||||||
// z2 = m^-1 mod n
|
// z2 = m^-1 mod n
|
||||||
//
|
//
|
||||||
// x = a2*y2*z2 = 1 * m * [m^-1 mod n]
|
// x = a2*y2*z2 = 1 * m * [m^-1 mod n]
|
||||||
func (this *ThresholdKeyGenerator) InitD() {
|
func (this *ThresholdKeyGenerator) initD() {
|
||||||
mInverse := new(big.Int).ModInverse(this.m, this.n)
|
mInverse := new(big.Int).ModInverse(this.m, this.n)
|
||||||
this.d = new(big.Int).Mul(mInverse, this.m)
|
this.d = new(big.Int).Mul(mInverse, this.m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) InitNumerialValues() error {
|
func (this *ThresholdKeyGenerator) initNumerialValues() error {
|
||||||
if err := this.InitPsAndQs(); err != nil {
|
if err := this.initPsAndQs(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
this.InitShortcuts()
|
this.initShortcuts()
|
||||||
this.InitD()
|
this.initD()
|
||||||
return this.ComputeV()
|
return this.computeV()
|
||||||
}
|
}
|
||||||
|
|
||||||
// f(X) = a_0 X^0 + a_1 X^1 + ... + a_(w-1) X^(w-1)
|
// f(X) = a_0 X^0 + a_1 X^1 + ... + a_(w-1) X^(w-1)
|
||||||
@@ -158,7 +158,7 @@ func (this *ThresholdKeyGenerator) InitNumerialValues() error {
|
|||||||
// `w` - threshold
|
// `w` - threshold
|
||||||
// `a_i` - random value from {0, ... nm - 1} for 0<i<w
|
// `a_i` - random value from {0, ... nm - 1} for 0<i<w
|
||||||
// `a_0` is always equal `d`
|
// `a_0` is always equal `d`
|
||||||
func (this *ThresholdKeyGenerator) GenerateHidingPolynomial() error {
|
func (this *ThresholdKeyGenerator) generateHidingPolynomial() error {
|
||||||
this.polynomialCoefficients = make([]*big.Int, this.Threshold)
|
this.polynomialCoefficients = make([]*big.Int, this.Threshold)
|
||||||
this.polynomialCoefficients[0] = this.d
|
this.polynomialCoefficients[0] = this.d
|
||||||
var err error
|
var err error
|
||||||
@@ -173,7 +173,7 @@ func (this *ThresholdKeyGenerator) GenerateHidingPolynomial() error {
|
|||||||
|
|
||||||
// The secred share of the i'th authority is `f(i)`, where `f` is
|
// The secred share of the i'th authority is `f(i)`, where `f` is
|
||||||
// the polynomial we generated in `GenerateHidingPolynomial` function.
|
// the polynomial we generated in `GenerateHidingPolynomial` function.
|
||||||
func (this *ThresholdKeyGenerator) ComputeShare(index int) *big.Int {
|
func (this *ThresholdKeyGenerator) computeShare(index int) *big.Int {
|
||||||
share := big.NewInt(0)
|
share := big.NewInt(0)
|
||||||
for i := 0; i < this.Threshold; i++ {
|
for i := 0; i < this.Threshold; i++ {
|
||||||
a := this.polynomialCoefficients[i]
|
a := this.polynomialCoefficients[i]
|
||||||
@@ -184,15 +184,15 @@ func (this *ThresholdKeyGenerator) ComputeShare(index int) *big.Int {
|
|||||||
return new(big.Int).Mod(share, this.nm)
|
return new(big.Int).Mod(share, this.nm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) CreateShares() []*big.Int {
|
func (this *ThresholdKeyGenerator) createShares() []*big.Int {
|
||||||
shares := make([]*big.Int, this.TotalNumberOfDecryptionServers)
|
shares := make([]*big.Int, this.TotalNumberOfDecryptionServers)
|
||||||
for i := 0; i < this.TotalNumberOfDecryptionServers; i++ {
|
for i := 0; i < this.TotalNumberOfDecryptionServers; i++ {
|
||||||
shares[i] = this.ComputeShare(i)
|
shares[i] = this.computeShare(i)
|
||||||
}
|
}
|
||||||
return shares
|
return shares
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) Delta() *big.Int {
|
func (this *ThresholdKeyGenerator) delta() *big.Int {
|
||||||
return Factorial(this.TotalNumberOfDecryptionServers)
|
return Factorial(this.TotalNumberOfDecryptionServers)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,9 +205,9 @@ func (this *ThresholdKeyGenerator) Delta() *big.Int {
|
|||||||
// `l` is the number of decryption servers
|
// `l` is the number of decryption servers
|
||||||
// `s_i` is a secret share for server `i`.
|
// `s_i` is a secret share for server `i`.
|
||||||
// Secret shares were previously generated in the `CrateShares` function.
|
// Secret shares were previously generated in the `CrateShares` function.
|
||||||
func (this *ThresholdKeyGenerator) CreateViArray(shares []*big.Int) (viArray []*big.Int) {
|
func (this *ThresholdKeyGenerator) createViArray(shares []*big.Int) (viArray []*big.Int) {
|
||||||
viArray = make([]*big.Int, len(shares))
|
viArray = make([]*big.Int, len(shares))
|
||||||
delta := this.Delta()
|
delta := this.delta()
|
||||||
for i, share := range shares {
|
for i, share := range shares {
|
||||||
tmp := new(big.Int).Mul(share, delta)
|
tmp := new(big.Int).Mul(share, delta)
|
||||||
viArray[i] = new(big.Int).Exp(this.v, tmp, this.nSquare)
|
viArray[i] = new(big.Int).Exp(this.v, tmp, this.nSquare)
|
||||||
@@ -215,7 +215,7 @@ func (this *ThresholdKeyGenerator) CreateViArray(shares []*big.Int) (viArray []*
|
|||||||
return viArray
|
return viArray
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) CreatePrivateKey(i int, share *big.Int, viArray []*big.Int) *ThresholdPrivateKey {
|
func (this *ThresholdKeyGenerator) createPrivateKey(i int, share *big.Int, viArray []*big.Int) *ThresholdPrivateKey {
|
||||||
ret := new(ThresholdPrivateKey)
|
ret := new(ThresholdPrivateKey)
|
||||||
ret.N = this.n
|
ret.N = this.n
|
||||||
ret.G = new(big.Int).Add(ret.N, ONE)
|
ret.G = new(big.Int).Add(ret.N, ONE)
|
||||||
@@ -229,22 +229,22 @@ func (this *ThresholdKeyGenerator) CreatePrivateKey(i int, share *big.Int, viArr
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) CreatePrivateKeys() []*ThresholdPrivateKey {
|
func (this *ThresholdKeyGenerator) createPrivateKeys() []*ThresholdPrivateKey {
|
||||||
shares := this.CreateShares()
|
shares := this.createShares()
|
||||||
viArray := this.CreateViArray(shares)
|
viArray := this.createViArray(shares)
|
||||||
ret := make([]*ThresholdPrivateKey, this.TotalNumberOfDecryptionServers)
|
ret := make([]*ThresholdPrivateKey, this.TotalNumberOfDecryptionServers)
|
||||||
for i := 0; i < this.TotalNumberOfDecryptionServers; i++ {
|
for i := 0; i < this.TotalNumberOfDecryptionServers; i++ {
|
||||||
ret[i] = this.CreatePrivateKey(i, shares[i], viArray)
|
ret[i] = this.createPrivateKey(i, shares[i], viArray)
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *ThresholdKeyGenerator) Generate() ([]*ThresholdPrivateKey, error) {
|
func (this *ThresholdKeyGenerator) Generate() ([]*ThresholdPrivateKey, error) {
|
||||||
if err := this.InitNumerialValues(); err != nil {
|
if err := this.initNumerialValues(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := this.GenerateHidingPolynomial(); err != nil {
|
if err := this.generateHidingPolynomial(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return this.CreatePrivateKeys(), nil
|
return this.createPrivateKeys(), nil
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ func TestGenerateSafePrimesOfThresholdKeyGenerator(t *testing.T) {
|
|||||||
tkh := new(ThresholdKeyGenerator)
|
tkh := new(ThresholdKeyGenerator)
|
||||||
tkh.nbits = 10
|
tkh.nbits = 10
|
||||||
tkh.Random = rand.Reader
|
tkh.Random = rand.Reader
|
||||||
p, q, err := tkh.GenerateSafePrimes()
|
p, q, err := tkh.generateSafePrimes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
@@ -29,7 +29,7 @@ func TestInitPandP1(t *testing.T) {
|
|||||||
tkh.nbits = 10
|
tkh.nbits = 10
|
||||||
tkh.Random = rand.Reader
|
tkh.Random = rand.Reader
|
||||||
|
|
||||||
tkh.InitPandP1()
|
tkh.initPandP1()
|
||||||
AreSafePrimes(tkh.p, tkh.p1, 10, t)
|
AreSafePrimes(tkh.p, tkh.p1, 10, t)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ func TestInitQandQ1(t *testing.T) {
|
|||||||
tkh.nbits = 10
|
tkh.nbits = 10
|
||||||
tkh.Random = rand.Reader
|
tkh.Random = rand.Reader
|
||||||
|
|
||||||
tkh.InitQandQ1()
|
tkh.initQandQ1()
|
||||||
AreSafePrimes(tkh.q, tkh.q1, 10, t)
|
AreSafePrimes(tkh.q, tkh.q1, 10, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ func TestInitPsAndQs(t *testing.T) {
|
|||||||
tkh.nbits = 10
|
tkh.nbits = 10
|
||||||
tkh.Random = rand.Reader
|
tkh.Random = rand.Reader
|
||||||
|
|
||||||
tkh.InitPsAndQs()
|
tkh.initPsAndQs()
|
||||||
AreSafePrimes(tkh.q, tkh.q1, 10, t)
|
AreSafePrimes(tkh.q, tkh.q1, 10, t)
|
||||||
AreSafePrimes(tkh.q, tkh.q1, 10, t)
|
AreSafePrimes(tkh.q, tkh.q1, 10, t)
|
||||||
}
|
}
|
||||||
@@ -56,17 +56,17 @@ func TestInitPsAndQs(t *testing.T) {
|
|||||||
func TestArePsAndQsGood(t *testing.T) {
|
func TestArePsAndQsGood(t *testing.T) {
|
||||||
tkh := new(ThresholdKeyGenerator)
|
tkh := new(ThresholdKeyGenerator)
|
||||||
tkh.p, tkh.p1, tkh.q, tkh.q1 = b(6), b(5), b(4), b(3)
|
tkh.p, tkh.p1, tkh.q, tkh.q1 = b(6), b(5), b(4), b(3)
|
||||||
if !tkh.ArePsAndQsGood() {
|
if !tkh.arePsAndQsGood() {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
tkh.p, tkh.p1, tkh.q, tkh.q1 = b(6), b(5), b(6), b(3)
|
tkh.p, tkh.p1, tkh.q, tkh.q1 = b(6), b(5), b(6), b(3)
|
||||||
if tkh.ArePsAndQsGood() {
|
if tkh.arePsAndQsGood() {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
tkh.p, tkh.p1, tkh.q, tkh.q1 = b(6), b(5), b(5), b(3)
|
tkh.p, tkh.p1, tkh.q, tkh.q1 = b(6), b(5), b(5), b(3)
|
||||||
if tkh.ArePsAndQsGood() {
|
if tkh.arePsAndQsGood() {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ func TestArePsAndQsGood(t *testing.T) {
|
|||||||
func TestInitShortcuts(t *testing.T) {
|
func TestInitShortcuts(t *testing.T) {
|
||||||
tkh := new(ThresholdKeyGenerator)
|
tkh := new(ThresholdKeyGenerator)
|
||||||
tkh.p, tkh.p1, tkh.q, tkh.q1 = b(11), b(7), b(5), b(3)
|
tkh.p, tkh.p1, tkh.q, tkh.q1 = b(11), b(7), b(5), b(3)
|
||||||
tkh.InitShortcuts()
|
tkh.initShortcuts()
|
||||||
|
|
||||||
if n(tkh.n) != 11*5 {
|
if n(tkh.n) != 11*5 {
|
||||||
t.Error("wrong n", tkh.n)
|
t.Error("wrong n", tkh.n)
|
||||||
@@ -93,8 +93,8 @@ func TestInitShortcuts(t *testing.T) {
|
|||||||
func TestInitD(t *testing.T) {
|
func TestInitD(t *testing.T) {
|
||||||
tkh := new(ThresholdKeyGenerator)
|
tkh := new(ThresholdKeyGenerator)
|
||||||
tkh.p, tkh.p1, tkh.q, tkh.q1 = b(863), b(431), b(839), b(419)
|
tkh.p, tkh.p1, tkh.q, tkh.q1 = b(863), b(431), b(839), b(419)
|
||||||
tkh.InitShortcuts()
|
tkh.initShortcuts()
|
||||||
tkh.InitD()
|
tkh.initD()
|
||||||
if n(tkh.d)%n(tkh.m) != 0 {
|
if n(tkh.d)%n(tkh.m) != 0 {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ func TestInitNumerialValues(t *testing.T) {
|
|||||||
tkh.nbits = 10
|
tkh.nbits = 10
|
||||||
tkh.Random = rand.Reader
|
tkh.Random = rand.Reader
|
||||||
|
|
||||||
if err := tkh.InitNumerialValues(); err != nil {
|
if err := tkh.initNumerialValues(); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -118,11 +118,11 @@ func TestGenerateHidingPolynomial(t *testing.T) {
|
|||||||
tkh.nbits = 10
|
tkh.nbits = 10
|
||||||
tkh.Threshold = 10
|
tkh.Threshold = 10
|
||||||
tkh.Random = rand.Reader
|
tkh.Random = rand.Reader
|
||||||
if err := tkh.InitNumerialValues(); err != nil {
|
if err := tkh.initNumerialValues(); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := tkh.GenerateHidingPolynomial(); err != nil {
|
if err := tkh.generateHidingPolynomial(); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
p := tkh.polynomialCoefficients
|
p := tkh.polynomialCoefficients
|
||||||
@@ -147,7 +147,7 @@ func TestComputeShare(t *testing.T) {
|
|||||||
tkh.TotalNumberOfDecryptionServers = 5
|
tkh.TotalNumberOfDecryptionServers = 5
|
||||||
tkh.nm = b(103)
|
tkh.nm = b(103)
|
||||||
tkh.polynomialCoefficients = []*big.Int{b(29), b(88), b(51)}
|
tkh.polynomialCoefficients = []*big.Int{b(29), b(88), b(51)}
|
||||||
share := tkh.ComputeShare(2)
|
share := tkh.computeShare(2)
|
||||||
if n(share) != 31 {
|
if n(share) != 31 {
|
||||||
t.Error("error computing a share. ", share)
|
t.Error("error computing a share. ", share)
|
||||||
}
|
}
|
||||||
@@ -159,16 +159,16 @@ func TestCreateShares(t *testing.T) {
|
|||||||
tkh.Threshold = 10
|
tkh.Threshold = 10
|
||||||
tkh.TotalNumberOfDecryptionServers = 100
|
tkh.TotalNumberOfDecryptionServers = 100
|
||||||
tkh.Random = rand.Reader
|
tkh.Random = rand.Reader
|
||||||
if err := tkh.InitNumerialValues(); err != nil {
|
if err := tkh.initNumerialValues(); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := tkh.GenerateHidingPolynomial(); err != nil {
|
if err := tkh.generateHidingPolynomial(); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if shares := tkh.CreateShares(); len(shares) != 100 {
|
if shares := tkh.createShares(); len(shares) != 100 {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ func TestCreateViArray(t *testing.T) {
|
|||||||
tkh.TotalNumberOfDecryptionServers = 10
|
tkh.TotalNumberOfDecryptionServers = 10
|
||||||
tkh.v = b(54)
|
tkh.v = b(54)
|
||||||
tkh.nSquare = b(101 * 101)
|
tkh.nSquare = b(101 * 101)
|
||||||
vArr := tkh.CreateViArray([]*big.Int{b(12), b(90), b(103)})
|
vArr := tkh.createViArray([]*big.Int{b(12), b(90), b(103)})
|
||||||
exp := []*big.Int{b(6162), b(304), b(2728)}
|
exp := []*big.Int{b(6162), b(304), b(2728)}
|
||||||
if !reflect.DeepEqual(vArr, exp) {
|
if !reflect.DeepEqual(vArr, exp) {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
@@ -187,7 +187,7 @@ func TestCreateViArray(t *testing.T) {
|
|||||||
|
|
||||||
func TestGetThresholdKeyGenerator(t *testing.T) {
|
func TestGetThresholdKeyGenerator(t *testing.T) {
|
||||||
tkh := GetThresholdKeyGenerator(50, 10, 6, rand.Reader)
|
tkh := GetThresholdKeyGenerator(50, 10, 6, rand.Reader)
|
||||||
if err := tkh.InitNumerialValues(); err != nil {
|
if err := tkh.initNumerialValues(); err != nil {
|
||||||
t.Error(nil)
|
t.Error(nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ func TestComputeV(t *testing.T) {
|
|||||||
tkh.n = b(1907 * 1823)
|
tkh.n = b(1907 * 1823)
|
||||||
tkh.nSquare = new(big.Int).Mul(tkh.n, tkh.n)
|
tkh.nSquare = new(big.Int).Mul(tkh.n, tkh.n)
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
if err := tkh.ComputeV(); err != nil {
|
if err := tkh.computeV(); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user