/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

/* test driver and function exerciser for BLS API Functions */

package main

import "fmt"

import "github.com/milagro-crypto/amcl/version3/go/amcl"

import "github.com/milagro-crypto/amcl/version3/go/amcl/BN254"
import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS383"
import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS24"
import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS48"

func printBinary(array []byte) {
	for i := 0; i < len(array); i++ {
		fmt.Printf("%02x", array[i])
	}
	fmt.Printf("\n")
}

func bls_BN254(rng *amcl.RAND) {

	const BGS = BN254.BGS
	const BFS = BN254.BFS
	const G1S = BFS + 1 /* Group 1 Size */
	const G2S = 4 * BFS /* Group 2 Size */

	var S [BGS]byte
	var W [G2S]byte
	var SIG [G1S]byte

	fmt.Printf("\nTesting Boneh-Lynn-Shacham BLS signature code\n")
	mess := "This is a test message"

	BN254.KeyPairGenerate(rng, S[:], W[:])
	fmt.Printf("Private key : 0x")
	printBinary(S[:])
	fmt.Printf("Public  key : 0x")
	printBinary(W[:])

	BN254.Sign(SIG[:], mess, S[:])
	fmt.Printf("Signature : 0x")
	printBinary(SIG[:])

	res := BN254.Verify(SIG[:], mess, W[:])

	if res == 0 {
		fmt.Printf("Signature is OK\n")
	} else {
		fmt.Printf("Signature is *NOT* OK\n")
	}
}

func bls_BLS383(rng *amcl.RAND) {

	const BGS = BLS383.BGS
	const BFS = BLS383.BFS
	const G1S = BFS + 1 /* Group 1 Size */
	const G2S = 4 * BFS /* Group 2 Size */

	var S [BGS]byte
	var W [G2S]byte
	var SIG [G1S]byte

	fmt.Printf("\nTesting Boneh-Lynn-Shacham BLS signature code\n")
	mess := "This is a test message"

	BLS383.KeyPairGenerate(rng, S[:], W[:])
	fmt.Printf("Private key : 0x")
	printBinary(S[:])
	fmt.Printf("Public  key : 0x")
	printBinary(W[:])

	BLS383.Sign(SIG[:], mess, S[:])
	fmt.Printf("Signature : 0x")
	printBinary(SIG[:])

	res := BLS383.Verify(SIG[:], mess, W[:])

	if res == 0 {
		fmt.Printf("Signature is OK\n")
	} else {
		fmt.Printf("Signature is *NOT* OK\n")
	}
}

func bls_BLS24(rng *amcl.RAND) {

	const BGS = BLS24.BGS
	const BFS = BLS24.BFS
	const G1S = BFS + 1 /* Group 1 Size */
	const G2S = 8 * BFS /* Group 2 Size */

	var S [BGS]byte
	var W [G2S]byte
	var SIG [G1S]byte

	fmt.Printf("\nTesting Boneh-Lynn-Shacham BLS signature code\n")
	mess := "This is a test message"

	BLS24.KeyPairGenerate(rng, S[:], W[:])
	fmt.Printf("Private key : 0x")
	printBinary(S[:])
	fmt.Printf("Public  key : 0x")
	printBinary(W[:])

	BLS24.Sign(SIG[:], mess, S[:])
	fmt.Printf("Signature : 0x")
	printBinary(SIG[:])

	res := BLS24.Verify(SIG[:], mess, W[:])

	if res == 0 {
		fmt.Printf("Signature is OK\n")
	} else {
		fmt.Printf("Signature is *NOT* OK\n")
	}
}

func bls_BLS48(rng *amcl.RAND) {

	const BGS = BLS48.BGS
	const BFS = BLS48.BFS
	const G1S = BFS + 1  /* Group 1 Size */
	const G2S = 16 * BFS /* Group 2 Size */

	var S [BGS]byte
	var W [G2S]byte
	var SIG [G1S]byte

	fmt.Printf("\nTesting Boneh-Lynn-Shacham BLS signature code\n")
	mess := "This is a test message"

	BLS48.KeyPairGenerate(rng, S[:], W[:])
	fmt.Printf("Private key : 0x")
	printBinary(S[:])
	fmt.Printf("Public  key : 0x")
	printBinary(W[:])

	BLS48.Sign(SIG[:], mess, S[:])
	fmt.Printf("Signature : 0x")
	printBinary(SIG[:])

	res := BLS48.Verify(SIG[:], mess, W[:])

	if res == 0 {
		fmt.Printf("Signature is OK\n")
	} else {
		fmt.Printf("Signature is *NOT* OK\n")
	}
}

func main() {
	rng := amcl.NewRAND()
	var raw [100]byte
	for i := 0; i < 100; i++ {
		raw[i] = byte(i + 1)
	}
	rng.Seed(100, raw[:])

	bls_BN254(rng)
	bls_BLS383(rng)
	bls_BLS24(rng)
	bls_BLS48(rng)

}
