initial version of SQIsign

Co-authored-by: Jorge Chavez-Saab <jorgechavezsaab@gmail.com>
Co-authored-by: Maria Corte-Real Santos <36373796+mariascrs@users.noreply.github.com>
Co-authored-by: Luca De Feo <github@defeo.lu>
Co-authored-by: Jonathan Komada Eriksen <jonathan.eriksen97@gmail.com>
Co-authored-by: Basil Hess <bhe@zurich.ibm.com>
Co-authored-by: Antonin Leroux <18654258+tonioecto@users.noreply.github.com>
Co-authored-by: Patrick Longa <plonga@microsoft.com>
Co-authored-by: Lorenz Panny <lorenz@yx7.cc>
Co-authored-by: Francisco Rodríguez-Henríquez <francisco.rodriguez@tii.ae>
Co-authored-by: Sina Schaeffler <108983332+syndrakon@users.noreply.github.com>
Co-authored-by: Benjamin Wesolowski <19474926+Calodeon@users.noreply.github.com>
This commit is contained in:
SQIsign team
2023-06-01 00:00:00 +00:00
committed by Lorenz Panny
commit 28ff420dd0
285 changed files with 70301 additions and 0 deletions

107
scripts/IntBigTest.scala Normal file
View File

@@ -0,0 +1,107 @@
/**
* Code to analyze instrumented code from the SQIsign IntBig module.
*
* Features:
* - verifies arithmetic
* - aggregate number of errors / ok per function
* - aggregate minimum / maximum values per function
*
* Prerequisite: enable debug output in intbig.x: #define DEBUG_VERBOSE
* Usage: ./<test app> | scala IntBigTest.scala
* Usage with unit test: sqisign_test_intbig <reps> <bits> | scala IntBigTest.scala
*
* Run option -v: verbose full output
*/
object IntBigTest {
// Test functions
object IntBigTestFuns {
def ibz_add(a: Array[BigInt]) = IntBigRes(a(0) == a(1) + a(2), a(1) + a(2), a)
def ibz_sub(a: Array[BigInt]) = IntBigRes(a(0) == a(1) - a(2), a(1) - a(2), a)
def ibz_mul(a: Array[BigInt]) = IntBigRes(a(0) == a(1) * a(2), a(1) * a(2), a)
def ibz_div(a: Array[BigInt]) = IntBigRes(a(0) == a(2) / a(3) && a(1) == a(2) % a(3), a(2) / a(3), a)
def ibz_pow_mod(a: Array[BigInt]) = IntBigRes(a(0) == a(1).modPow(a(2), a(3)), a(1).modPow(a(2), a(3)), a)
def ibz_cmp(a: Array[BigInt]) = IntBigRes(
if (a(1) == a(2)) a(0) == 0 else if (a(1) < a(2)) a(0) < 0 else a(0) > 0,
if (a(1) == a(2)) -1 else if (a(1) < a(2)) 1 else 0,
a)
def ibz_is_zero(a: Array[BigInt]) = IntBigRes(if (a(1) == 0) a(0) == 1 else a(0) == 0, if (a(1) == 0) 1 else 0, a)
def ibz_is_one(a: Array[BigInt]) = IntBigRes(if (a(1) == 1) a(0) == 1 else a(0) == 0, if (a(1) == 1) 1 else 0, a)
def ibz_probab_prime(a: Array[BigInt]) = IntBigRes(if (a(1).isProbablePrime(a(2).toInt)) a(0) > 0 else a(0) == 0, if (a(1).isProbablePrime(a(2).toInt)) 1 else 0, a)
def ibz_gcd(a: Array[BigInt]) = IntBigRes(a(1).gcd(a(2)) == a(0), a(1).gcd(a(2)), a)
def ibz_sqrt_mod_p(in: Array[BigInt]): IntBigRes = {
val sqrt = in(0)
val p = in(2)
val a = if (in(1).mod(p) < 0) p + in(1).mod(p) else in(1).mod(p)
val exp0 = sqrt.modPow(2, p)
IntBigRes(exp0 == a || (p - exp0) == a, sqrt.modPow(2, p), in)
}
def ibz_sqrt_mod_2p(a: Array[BigInt]): IntBigRes = IntBigRes(a(0).modPow(2, 2 * a(2)) == a(1), a(0), a)
}
val funList = Map(
//"ibz_add" -> ibz_add _,
"ibz_sqrt_mod_p" -> IntBigTestFuns.ibz_sqrt_mod_p _,
"ibz_sqrt_mod_2p" -> IntBigTestFuns.ibz_sqrt_mod_2p _,
"ibz_add" -> IntBigTestFuns.ibz_add _,
"ibz_sub" -> IntBigTestFuns.ibz_sub _,
"ibz_mul" -> IntBigTestFuns.ibz_mul _,
"ibz_div" -> IntBigTestFuns.ibz_div _,
"ibz_pow_mod" -> IntBigTestFuns.ibz_pow_mod _,
"ibz_cmp" -> IntBigTestFuns.ibz_cmp _,
"ibz_is_zero" -> IntBigTestFuns.ibz_is_zero _,
"ibz_is_one" -> IntBigTestFuns.ibz_is_one _,
"ibz_probab_prime" -> IntBigTestFuns.ibz_probab_prime _,
"ibz_gcd" -> IntBigTestFuns.ibz_gcd _
)
case class AggregateResults(funName: String, errors: Int, ok: Int, max: Option[Int], min: Option[Int]) {
def errInc = AggregateResults(funName, errors + 1, ok, max, min)
def okInc(operands: List[BigInt]) = {
val operandsBitLen = operands.map(_.bitLength)
val newMax = Some((max.getOrElse(0) :: operandsBitLen).max)
val newMin = Some((min.getOrElse(Int.MaxValue) :: operandsBitLen).min)
AggregateResults(funName, errors, ok + 1, newMax, newMin)
}
override def toString: String = s"$funName: $errors errors, $ok ok, max value: ${max.getOrElse(BigInt(0))} bits, min value: ${min.getOrElse(BigInt(0))} bits)"
}
def main(args: Array[String]) = {
val v = args.length >= 1 && args(0) == "-v"
var err = Map() ++ funList.map(i => (i._1 -> AggregateResults(i._1, 0, 0, None, None)))
var cont = true
while (cont) {
val l = scala.io.StdIn.readLine()
if (l == null) {
val numerr =
err.foreach(i => println(i._2))
println(s"==========\n${err.values.map(_.errors).sum} errors found\n${err.values.map(_.ok).sum} checks ok")
cont = false
} else {
err = check(l, v, err)
}
}
}
case class IntBigRes(verif: Boolean, expected: BigInt, got: Array[BigInt])
def check(line: String, v: Boolean, agg: Map[String, AggregateResults]): Map[String, AggregateResults] = {
line.split(",").toList match {
case x :: xs if funList.contains(x) =>
val funA = xs.map(i => BigInt(i, 16)).toArray
funList(x)(funA) match {
case IntBigRes(false, exp, got) =>
println(s"function: $x\ngot:\n${got.map(_.toString(16)).mkString(",")}\nexpected:\n${exp.toString(16)}")
agg.map(i => if (i._1 == x) i._1 -> i._2.errInc else i)
case _ =>
agg.map(i => if (i._1 == x) i._1 -> i._2.okInc(funA.toList) else i)
}
case _ =>
if (v) println(line)
agg
}
}
}