HIT·信息安全数学基础·实验三

实验背景

有限域亦称伽罗瓦域(Galois Fields),是伽罗瓦于 18 世纪 30 年代研究代数
方程根式求解问题时引出的概念。有限域在密码学、近代编码、计算机理论、组
合数学等方面有着广泛的应用。
本次实验要求同学们利用 Java 或者其他编程语言对有限域四则运算算法和
有限域欧几里得算法进行实践。
本次实验的目的包括:

  1. 理解和掌握有限域的概念,以及有限域在计算机领域的应用。
  2. 了解有限域四则运算算法和有限域欧几里得算法的流程,将其和整数四则
    运算以及整数欧几里得算法进行对比。
  3. 编码实践有限域四则运算算法和有限域欧几里得算法。

实验内容

有限域四则运算算法

实验代码

package FiniteField;

import java.math.BigInteger;
import java.util.Random;
import java.util.Scanner;

public abstract class FiniteField {
    //GF(2)上,加减法等价,都是异或运算
    public int addorMinus(int a1, int a2) {
        return a1 ^ a2;
    }


    public int multiply(int a1, int a2, int poly) {
        int result = 0;
        for (int i = 0; i < 8; i++) {
            // Step 3: If the lowest bit of a2 is 1, xor a1 with result
            if ((a2 & 1) != 0) {
                result ^= a1;
            }
            // Left shift a1
            a1 <<= 1;
            // Step 4: If the highest bit of a1 (now 9th bit) is 1, xor a1 with poly
            if ((a1 & 0x100) != 0) {
                a1 ^= poly;
            }
            // Ensure a1 stays within 8 bits
            a1 &= 0xFF;
            // Step 5: Right shift a2
            a2 >>= 1;
        }
        return result;
    }



    public int divide(int a1, int a2) {
        int ans = 0;
        while (bitLength(a1) >= bitLength(a2)) {
            int rec = bitLength(a1) - bitLength(a2);
            a1 ^= (a2 << rec);
            ans ^= (1 << rec);
        }
        return ans;
    }

    // 辅助函数,计算数字的二进制长度
    private int bitLength(int a) {
        int length = 0;
        while (a != 0) {
            length++;
            a >>= 1;
        }
        return length;
    }



    public int euclid(int a1, int a2) {
        while (a2 != 0) {
            // 使用多项式除法计算余数
            int temp = mod(a1, a2);
            a1 = a2;
            a2 = temp;
        }
        return a1;
    }

    // 辅助函数,计算多项式除法的余数
    private int mod(int a, int b) {
        if (bitLength(a) < bitLength(b)) {
            return a;
        }
        int div = divide(a, b);
        return a ^ multiply(div, b, 0x11b); // a - (div * b) 在 GF(2^n) 中
    }


//    public int inverse(int a, int m) {
//        int b = m, x0 = 1, x1 = 0, temp;
//
//        while (a > 1 && b != 0) {
//            int q = divide(a, b);
//            int r = mod(a, b); // 多项式取余
//            a = b;
//            b = r;
//
//            temp = x1;
//            x1 = addorMinus(x0, multiply(q, x1, m)); // GF(2^n)中的减法实际上是加法
//            x0 = temp;
//        }
//
//        if (a != 1) { // 如果a不等于1,说明没有逆元
//            return 0;
//        }
//
//        return x0;
//    }
public int inverse(int a, int m) {
    int b = m, x0 = 1, x1 = 0, temp;

    while (a != 0) {
        while ((a & 1) == 0) {
            a >>= 1;
            x0 = (x0 & 1) != 0 ? addorMinus(x0, m) >> 1 : x0 >> 1;
        }

        while ((b & 1) == 0) {
            b >>= 1;
            x1 = (x1 & 1) != 0 ? addorMinus(x1, m) >> 1 : x1 >> 1;
        }

        if (a >= b) {
            a = addorMinus(a, b);
            x0 = addorMinus(x0, x1);
        } else {
            b = addorMinus(b, a);
            x1 = addorMinus(x1, x0);
        }
    }

    if (b != 1) { // 如果b不等于1,说明没有逆元
        return 0;
    }

    return x1;
}




    public static void main(String[] args) {
        FiniteField ff = new FiniteField() {};
        int res;

        // 有限域四则运算算法测试
        System.out.printf("有限域加法\n");
        System.out.printf("0x89 + 0x4d = 0xc4");
        res = ff.addorMinus(0x89, 0x4d);
        if (res == 0xc4)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("0xaf + 0x3b = 0x94");
        res = ff.addorMinus(0xaf, 0x3b);
        if (res == 0x94)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("0x35 + 0xc6 = 0xf3");
        res = ff.addorMinus(0x35, 0xc6);
        if (res == 0xf3)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }

        System.out.printf("有限域减法\n");
        System.out.printf("0x89 - 0x4d = 0xc4");
        res = ff.addorMinus(0x89, 0x4d);
        if (res == 0xc4)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("0x9f - 0x3b = 0xa4");
        res = ff.addorMinus(0x9f, 0x3b);
        if (res == 0xa4)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("0x35 - 0xc6 = 0xf3");
        res = ff.addorMinus(0x35, 0xc6);
        if (res == 0xf3)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }

        System.out.printf("有限域乘法\n");
        System.out.printf("0xce * 0xf1 = 0xef");
        res = ff.multiply(0xce, 0xf1, 0x11b);
        if (res == 0xef)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("0x70 * 0x99 = 0xa2");
        res = ff.multiply(0x70, 0x99, 0x11b);
        if (res == 0xa2)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("0x00 * 0xa4 = 0x00");
        res = ff.multiply(0x00, 0xa4, 0x11b);
        if (res == 0x00)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }

        System.out.printf("有限域除法\n");
        System.out.printf("0xde / 0xc6 = 0x01");
        res = ff.divide(0xde, 0xc6);
        if (res == 0x01)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("0x8c / 0x0a = 0x14");
        res = ff.divide(0x8c, 0x0a);
        if (res == 0x14)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("0x3e / 0xa4 = 0x00");
        res = ff.divide(0x3e, 0xa4);
        if (res == 0x00)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }


        // 有限域欧几里得算法测试
        System.out.printf("有限域欧几里得算法\n");
        System.out.printf("gcd(0x75, 0x35) = 0x01");
        res = ff.euclid(0x75, 0x35);
        if (res == 0x01)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("gcd(0xac, 0x59) = 0x03");
        res = ff.euclid(0xac, 0x59);
        if (res == 0x03)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("gcd(0xf8, 0x2e) = 0x02");
        res = ff.euclid(0xf8, 0x2e);
        if (res == 0x02)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("gcd(0x48, 0x99) = 0x09");
        res = ff.euclid(0x48, 0x99);
        if (res == 0x09)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }


        // 有限域求乘法逆元算法
        System.out.printf("有限域求乘法逆元\n");
        System.out.printf("inverse(0x8c) = 0xf7");
        res = ff.inverse(0x8c, 0x11b);
        if (res == 0xf7)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("inverse(0xbe) = 0x86");
        res = ff.inverse(0xbe, 0x11b);
        if (res == 0x86)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("inverse(0x01) = 0x01");
        res = ff.inverse(0x01, 0x11b);
        if (res == 0x01)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
        System.out.printf("inverse(0x2d) = 0x44");
        res = ff.inverse(0x2d, 0x11b);
        if (res == 0x44)
        {
            System.out.printf(", PASS!\n");
        }
        else
        {
            System.out.printf(", while your output is 0x%x, FAILED!\n", res);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值