메모장

블로그 이미지

동팡

https://github.com/ehdvudee

샤미르의 비밀 공유(SSS, Shamir's Secret Sharing) - 구현

개발관련/삽질 2020. 5. 12. 23:13

목차

 개요

 클래스 및 메소드 소개(중요사항만)

 코드 분석(중요사항만)

 

개요

SSS의 구현체를 분석한다. 분석 대상은 오픈 소스이다. 분석 대상 프로젝트의 링크는 다음과 같다.

https://github.com/timtiemens/secretshare

프로젝트 선정 기준은 다음과 같다.

  • 개발 언어 유형 – Java

  • 높은 스타 지수

  • 샘플 파일 및 최소한의 문서(READEME.md)

 클래스 및 메소드 소개(중요사항만)

[SecretShare.class(중요사항만 기재)]

내부 클래스 메소드 설명 비고
PublicInfo -

Secret Share를 생성하기 위한 공개 정보를 보관한다. 공개 정보는 아래와 같다.

-       k: (t, n) 구성 요소 중 t에 해당하는 값이다. 비밀을 만들기 위한 비밀 조각들의 임계치 값(최소 개수 값)

-       n: (t, n) 구성 요소 중 n에 해당하는 값이다. 생성하고자 하는 비밀 조각들의 개수이다.

-       primeModulus: 비밀을 만들 때 사용하는 소수 값이다.

-       Description Info: 기타 정보

모든 메소들은 유틸성이다.
 
SplitSecretOutput - split 메스도를 통해 반환되는 객체이다. 사용자는 해당 객체를 이용해서 시크릿 조각들을 사용할 수 있다.  
ShareInfo - 시크릿 조각을 갖고 있는 객체이다(x, y 값).  
CombineOutput - 시크릿 조각 조합 후의 객체  
- split 시크릿 조각들을 생성한다.  
- combine 시크릿 조각 조합(비밀 생성)  

[유틸 클래스(중요사항만 기재)]

내부 클래스 메소드 설명 비고
PolyEquationImpl

-

다항 방정식을 처리하는 유틸클래스이다.

 
calculateFofX

x 값을 정의하면, 해당 값으로 방정식의 계산을 실시한다. 예는 다음과 같다.

fx = 1234 + 166x + 94x2  

위의 값에 x가 1일 경우, 1494를 반환한다.

 
NumberSimplex -

선형대수 관련 연산을 할 때 사용.

시크릿 조각을 조립할 때 사용하는 핵심 클래스
 
BigRational - 큰 값의 유리수 처리  
Numbermatrix - Number를 확장한 객체에 대해 행렬을 형성해주는 클래스  

 

코드 분석(중요사항만)

[분석 대상]

- SecretShare.split 메소드

- SecretShare.combine 메소드

 

[SecretShare.split]

개요

예: PublicInfo객체의 맴버 변수를 다음과 같이 지정한다.

-       n = 16

-       k = 3

-       prime = 1613

위를 해석하면 16개의 조각을 생성하며, 3개의 조각은 임계치를 뜻한다. 즉, 3개의 조각이 존재할 경우 Secret을 생성할 수 있다. k가 3을 뜻하는 것은 이차방정식 그래프를 생성한 다는것이다. 예를 들면 아래와 같다(1234는 시크릿이다.).

 

 

코드 분석

        if (secret == null)
        {
            throw new SecretShareException("Secret cannot be null");
        }
        if (secret.signum() <= 0)
        {
            throw new SecretShareException("Secret cannot be negative");
        }
        if (publicInfo.getPrimeModulus() != null)
        {
            checkThatModulusIsAppropriate(publicInfo.getPrimeModulus(), secret);
        }

 - 유효성 검사를 실시한다.

 

BigInteger[] coeffs = new BigInteger[publicInfo.getK()];

 - k를 조회하여, k개의 계수를 생성한다 coeffs는 coefficient(계수)의 줄임말을 의미한다.

 - 계수 1개의 수준은 1개의 Array이다.

randomizeCoeffs(coeffs, random, publicInfo.getPrimeModulus(), secret);

private void randomizeCoeffs(final BigInteger[] coeffs, final Random random, final BigInteger modulus, final BigInteger secret)
    {
        for (int i = 1, n = coeffs.length; i < n; i++)
        {
            BigInteger big = null;

            //big = coeffGenOriginal(random); // see Issue#8
            big = coeffGenImproved(random, modulus);

            // FIX? TODO:? FIX?
            big = big.abs(); // make it positive

            coeffs[i] = big;

            // Book says "all coefficients are smaller than the modulus"
            if (modulus != null)
            {
                coeffs[i] = coeffs[i].mod(modulus);
            }

            // FIX? TODO: FIX? experiment says "all coefficients are smaller than the secret"
            coeffs[i] = coeffs[i].mod(secret);
        }
    }

 - Secret보다 작고, Prime보다 작은 Secret을 제외한 계수들을 생성한다.

 - 예를들면 S가 1234이고 k가 3일 때 S를 제외한 1차항, 2차항에 대해 랜덤 계수를 생성한다.

 - 0차항의 자리는 S 1234 값이 들어간다.

 

coeffs[0] = secret;

 - 0차 항은 S 값이다.

 

        SplitSecretOutput ret = new SplitSecretOutput(this.publicInfo, equation);

        for (int x = 1, n = publicInfo.getNforSplit() + 1; x < n; x++)
        {
            final BigInteger fofx = equation.calculateFofX(BigInteger.valueOf(x));
            BigInteger data = fofx;
            if (publicInfo.primeModulus != null)
            {
                data = data.mod(publicInfo.primeModulus);
            }
            final ShareInfo share = new ShareInfo(x, data, this.publicInfo);
            if (publicInfo.primeModulus != null)
            {
                if (data.compareTo(publicInfo.getPrimeModulus()) > 0)
                {
                    throw new RuntimeException("" + data + "\n" + publicInfo.getPrimeModulus() + "\n");
                }
            }
            ret.sharesInfo.add(share);
        }

        return ret;

 - x값은 1부터 시작하기 때문에 1부터 시작하여, n값(16) 까지 반복을 실시한다.

 - calculateFofX를 통해 방정식의 셈을 실시한다.

 - 해당 결과 값에 대해 mod를 실시한다.

 - 생성한 Secret 조각들은 ShareInfo 객체에 적재한다.

 - ShareInfo 객체는 SplitSecretOutput에 적재, 사용자는 최종적으로 SplitSecretOutput을 반환 받는다.

 - 해당 과정은 다음의 그림을 만드는 과정과 같다.

 

[SecretShare.combine]

개요

ShareInfo는 다음과 같다.

-       (1, 1494)

-       (2, 329)

-       (3, 965)

위의 ShareInfo 객체는 비밀을 만들기 위해 사용되는 비밀 조각들이다. 해당 조각들을 이용하여 combine 메소드를 실행한다. 해당 메소드는 불필요한 부분이 많기 때문에 해당 부분은 전부 설명에서 제외하였다.

 

코드 분석

        CombineOutput ret = null;

        sanityCheckPublicInfos(publicInfo, usetheseshares);

        if (true)
        {
            println(" SOLVING USING THESE SHARES, mod=" + publicInfo.getPrimeModulus());
            for (ShareInfo si : usetheseshares)
            {
                println("   " + si.share);
            }
            println("end SOLVING USING THESE SHARES");
        }
        if (publicInfo.getK() > usetheseshares.size())
        {
            throw new SecretShareException("Must have " + publicInfo.getK() +
                                           " shares to solve.  Only provided " +
                                           usetheseshares.size());
        }

        checkForDuplicatesOrThrow(usetheseshares);

예외 처리

 

            BigInteger[][] matrix = ele.getMatrix();
            NumberMatrix.print("SS.java", matrix, out);
            println("CVT matrix.height=" + matrix.length + " width=" + matrix[0].length);
            BigRationalMatrix brm = BigRationalMatrix.create(matrix);
            NumberMatrix.print("SS.java brm", brm.getArray(), out);

            NumberSimplex<BigRational> simplex = new NumberSimplex<BigRational>(brm, 0);
            simplex.initForSolve(out);
            simplex.solve(out);

            BigRational answer = simplex.getAnswer(1);
            if (publicInfo.getPrimeModulus() != null)
            {
                solveSecret = answer.computeBigIntegerMod(publicInfo.getPrimeModulus());
            }
            else
            {
                solveSecret = answer.bigIntegerValue();
            }

 - 제일 중요한 부분이다.

 - 역행렬 연산을 통해 선형 방정식을 계산한다.

 

 - simplex.initForSolve(out);

  -> 해당 메소드에서 역행렬을 진행하기 위한 행렬을 생성한다.

 

 - simplex.solve(out);

  -> 역행렬 작업을 진행한다.

  -> 역행렬 작업은 NumberSimplex.createAbar(E[][] array, int I, int j) 메소드에서 진행한다.

 

 - 위와 같은 선형 방정식 행렬을 역행렬 작업을 진행한다.

 - 위와 같이 3x3 행렬이 있다.

 - 역행렬 공식은 위와 같다. 위의 작업을 simplex.solve(out)에서 진행한다.

 

 - 역행렬 작업이 끝나면 위와 같이 행렬이 구성되어 있다.

 

 - 위의 행렬을 토대로 NumberSimplex.solve 메소드에서 computeAnswers 메소드를 통해 행렬 곱을 진행한다.

 

            BigRational answer = simplex.getAnswer(0);
            if (publicInfo.getPrimeModulus() != null)
            {
                solveSecret = answer.computeBigIntegerMod(publicInfo.getPrimeModulus());
            }
            else
            {
                solveSecret = answer.bigIntegerValue();
            }

 - simplex.getAnswer(0) // 리턴 씨크릿

 - modulo 1613 작업을 진행한다.

 

 

저작자표시 비영리 (새창열림)

'개발관련 > 삽질' 카테고리의 다른 글

LoRaWAN 1.1 보안 부분 분석(LoRa Spec 6장 일부분 번역)  (0) 2021.02.04
Java Enum 활용기(기본/활용/Spring/MyBatis/테스트까지)  (2) 2020.07.20
Python TensorFlow를 이용한 몸무게 예측 프로그램  (0) 2020.05.07
샤미르의 비밀 공유(SSS, Shamir's Secret Sharing) - 이론  (6) 2020.05.07
REST API 속도 개선(Java/Spring/Cache)  (0) 2020.02.27
Posted by 동팡
블로그 이미지

https://github.com/ehdvudee

by 동팡

공지사항

    최근...

  • 포스트
  • 댓글
  • 트랙백
  • 더 보기

태그

  • java
  • 이직 정보 공유
  • vault 개요
  • Hashicorp
  • 책리뷰
  • 이직 느낀점
  • 경력 채용
  • What is Vault
  • 네이버 비즈니스 플랫폼
  • Shamir Secret Sharing
  • Secret Sharing 이론
  • 네이버 클라우드
  • Spring
  • NBP
  • Thread-safe
  • vault tutorial
  • 글쓰기 가이드
  • LoRaWA
  • 개발자 글쓰기 책
  • 개발자 준비
  • 볼트란
  • 하시콥 볼트
  • vault
  • 간단리뷰
  • 네이버 클라우드 이직
  • Secret Sharing
  • 자바
  • 개발자 책리뷰
  • 개발자 이직
  • 네이버 클라우드 개발자 면접

글 보관함

«   2026/01   »
일 월 화 수 목 금 토
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

링크

카테고리

메모장 (73)
개발관련 (71)
삽질 (26)
(과거)메모 (27)
강의 (0)
회고 (9)
책 리뷰 (9)
블로그 관리 글(비공개) (0)
일상 (2)
기타 (0)
책 리뷰 (1)
회고 (0)

카운터

Total
Today
Yesterday
방명록 : 관리자 : 글쓰기
동팡's Blog is powered by daumkakao
Skin info material T Mark3 by 뭐하라
favicon

메모장

https://github.com/ehdvudee

  • 태그
  • 링크 추가
  • 방명록

관리자 메뉴

  • 관리자 모드
  • 글쓰기
  • 메모장 (73)
    • 개발관련 (71)
      • 삽질 (26)
      • (과거)메모 (27)
      • 강의 (0)
      • 회고 (9)
      • 책 리뷰 (9)
    • 블로그 관리 글(비공개) (0)
    • 일상 (2)
      • 기타 (0)
      • 책 리뷰 (1)
      • 회고 (0)

카테고리

PC화면 보기 티스토리 Daum

티스토리툴바