From ac1f3ec366557bcb7a2e196309b66d5225ba2314 Mon Sep 17 00:00:00 2001
From: Minyong Li <ml10g20@soton.ac.uk>
Date: Sun, 13 Jun 2021 18:18:25 +0100
Subject: [PATCH] core: impl QuarterRound{,Test}

---
 .../ac/soton/ecs/can/core/QuarterRound.scala  | 34 +++++++++++++++++
 .../soton/ecs/can/core/QuarterRoundTest.scala | 37 +++++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 src/main/scala/uk/ac/soton/ecs/can/core/QuarterRound.scala
 create mode 100644 src/test/scala/uk/ac/soton/ecs/can/core/QuarterRoundTest.scala

diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/QuarterRound.scala b/src/main/scala/uk/ac/soton/ecs/can/core/QuarterRound.scala
new file mode 100644
index 0000000..a60650d
--- /dev/null
+++ b/src/main/scala/uk/ac/soton/ecs/can/core/QuarterRound.scala
@@ -0,0 +1,34 @@
+package uk.ac.soton.ecs.can.core
+
+import chisel3._
+import chisel3.util._
+
+class QuarterRound extends Module {
+  val io = IO(new Bundle {
+    val in = Input(Vec(4, UInt(32.W)))
+    val out = Output(Vec(4, UInt(32.W)))
+  })
+
+  private def rotateLeft(v: UInt, b: Int): UInt =
+    Cat(v(31 - b, 0), v(31, 32 - b))
+
+  val a0 = io.in(0)
+  val b0 = io.in(1)
+  val c0 = io.in(2)
+  val d0 = io.in(3)
+
+  val a1 = a0 + b0
+  val d1 = rotateLeft(d0 ^ a1, 16)
+  val c1 = c0 + d1
+  val b1 = rotateLeft(b0 ^ c1, 12)
+
+  val a2 = a1 + b1
+  val d2 = rotateLeft(d1 ^ a2, 8)
+  val c2 = c1 + d2
+  val b2 = rotateLeft(b1 ^ c2, 7)
+
+  io.out(0) := a2
+  io.out(1) := b2
+  io.out(2) := c2
+  io.out(3) := d2
+}
diff --git a/src/test/scala/uk/ac/soton/ecs/can/core/QuarterRoundTest.scala b/src/test/scala/uk/ac/soton/ecs/can/core/QuarterRoundTest.scala
new file mode 100644
index 0000000..59f5c6d
--- /dev/null
+++ b/src/test/scala/uk/ac/soton/ecs/can/core/QuarterRoundTest.scala
@@ -0,0 +1,37 @@
+package uk.ac.soton.ecs.can.core
+
+import org.scalatest._
+import chiseltest._
+import chisel3._
+
+class QuarterRoundTest extends FlatSpec with ChiselScalatestTester {
+
+  it should "compute RFC8439 2.1.1 test vector correctly" in {
+    test(new QuarterRound) { c =>
+      c.io.in(0).poke("h11111111".U(32.W))
+      c.io.in(1).poke("h01020304".U(32.W))
+      c.io.in(2).poke("h9b8d6f43".U(32.W))
+      c.io.in(3).poke("h01234567".U(32.W))
+
+      c.io.out(0).expect("hea2a92f4".U(32.W))
+      c.io.out(1).expect("hcb1cf8ce".U(32.W))
+      c.io.out(2).expect("h4581472e".U(32.W))
+      c.io.out(3).expect("h5881c4bb".U(32.W))
+    }
+  }
+
+  it should "compute RFC8439 2.2.1 test vector correctly" in {
+    test(new QuarterRound) { c =>
+      c.io.in(0).poke("h516461b1".U(32.W))
+      c.io.in(1).poke("h2a5f714c".U(32.W))
+      c.io.in(2).poke("h53372767".U(32.W))
+      c.io.in(3).poke("h3d631689".U(32.W))
+
+      c.io.out(0).expect("hbdb886dc".U(32.W))
+      c.io.out(1).expect("hcfacafd2".U(32.W))
+      c.io.out(2).expect("he46bea80".U(32.W))
+      c.io.out(3).expect("hccc07c79".U(32.W))
+    }
+  }
+
+}
-- 
GitLab