NodeCrypto 도움말

내장 스크립트 개요

내장 스크립트 언어는 Script 노드 안에서 bytes, int, bool, string 값에 대한 데이터 의존적 연결 논리(조건 분기, 유한 반복, 사용자 정의 프레이밍, 보조 함수)를 표현하기 위해 설계된 결정적·정적 타입 Python 부분집합 언어이다.

읽기 전용 입력 bytes · int · bool · str Script 노드 평가기 정적 타입 검사 · 유한 반복문 24종 내장 함수 · 외부 입출력 없음 출력 포트 확정 대입 보장

암호 기본 연산은 전용 암호·해시·MAC·KDF·서명 노드가 담당하고, Script 노드는 그 사이의 바이트 단위 가공과 연결을 담당한다. 범용 Python 런타임이 아닌 NodeCrypto 자체 인터프리터가 실행하므로 웹앱, 데스크톱 앱, CLI, API Container 어디서나 완전히 동일하고 재현 가능한 결과를 보장한다.

설계 원칙

Script 노드 구성 요소

구성 요소설명
입력 포트각 입력 포트는 고유 식별자(id / 표시 이름)와 정적 데이터 타입(bytes, int, bool, string)을 가진다. 추가된 모든 입력 포트는 필수 입력이다.
출력 포트0개 이상의 출력 포트를 둘 수 있으며, 각 포트는 고유 식별자와 정적 데이터 타입(bytes, int, bool, string)을 가진다.
코드스크립트 소스 코드 (최대 64 KiB).

포트 이름이 스크립트 내부에서 변수 이름으로 직접 사용되므로, 모든 포트 이름은 식별자 규칙을 따라야 하며 예약어나 내장 함수 이름과 충돌할 수 없고 노드 내 모든 포트 통틀어 유일해야 한다. Script 노드에는 any나 set 타입 포트를 둘 수 없다.

입력·출력 포트 바인딩

실행 수명주기

  1. 연결된 모든 입력 포트에 값이 준비되면 Script 노드가 실행된다.
  2. 최상위 문장들이 위에서 아래로 순차 실행된다.
  3. 실행이 정상적으로 끝에 도달하면 출력 변수들에 담긴 값이 대응하는 출력 포트로 방출된다.
  4. fail(code, message)가 호출되거나 런타임 에러가 발생하거나 자원 한도를 초과하면 실행이 즉시 중단되며, 부분 출력은 방출되지 않고 노드는 ERROR 상태가 된다(에러 및 자원 한도 참고).

코드 편집기 사용

Script 노드 속성 창의 첫 번째 탭은 코드 편집기이며, 입력·출력 포트는 Ports 탭(또는 노드 카드)에서 관리한다. 정적 검사에서 오류가 발견되면 편집기가 해당 줄:열 위치와 진단 메시지를 표시하며 오류가 해결될 때까지 저장을 막는다.

검증된 예시

아래의 모든 예시는 내장 스크립트 평가기로 실제 실행하여 검증된 코드이다. 바이트 입출력은 16진수로 표기한다.

CMAC 서브키 파생 (조건 분기)

입력 l: bytes(16바이트 영 블록의 AES 암호화 결과), 출력 k1: bytes 및 k2: bytes. 입력이 7df76b0c1ab899b33e42f047b91b546f일 때 k1은 fbeed618357133667c85e08f7236a8de, k2는 f7ddac306ae266ccf90bc11ee46d513b이다(RFC 4493 테스트 벡터).

def dbl(x: bytes) -> bytes:
    rb = h"00" * (len(x) - 1) + (h"87" if len(x) == 16 else h"1b")
    r = x << 1
    if x[0] & 0x80 != 0:
        r ^= rb
    return r

k1 = dbl(l)
k2 = dbl(k1)

카운터 블록 시퀀스 생성 (리스트와 반복문)

입력 seed: bytes와 n: int, 출력 out: bytes. seed가 aa이고 n이 3일 때 aa00000000, aa00000001, aa00000002를 이어 붙인 바이트열을 만든다.

parts: list[bytes] = []
for i in range(n):
    parts += [seed + to_bytes(i, 4)]
out = concat(parts)

길이 검증 및 튜플 언패킹

입력 data: bytes, 출력 head: bytes와 body: bytes. 앞 4바이트를 헤더로, 나머지를 본문으로 분리한다. data가 0102030405이면 head는 01020304, body는 05이다.

def split2(b: bytes, n: int) -> tuple[bytes, bytes]:
    if len(b) < n:
        fail("DATA_TOO_SHORT", "data is shorter than the header")
    return b[:n], b[n:]

head, body = split2(data, 4)

같은 스크립트에 1바이트 입력 01을 전달하면 DATA_TOO_SHORT 에러가 발생하며 노드가 에러 상태로 전환된다:

def split2(b: bytes, n: int) -> tuple[bytes, bytes]:
    if len(b) < n:
        fail("DATA_TOO_SHORT", "data is shorter than the header")
    return b[:n], b[n:]

head, body = split2(data, 4)

DES 키 홀수 패리티 보정 (바이트 순회)

입력 key: bytes, 출력 fixed: bytes. 각 바이트의 1의 개수가 홀수가 되도록 최하위 비트를 조정한다. 입력 0022ff00에 대해 0123fe01을 출력한다.

out: list[int] = []
for v in key:
    ones = 0
    for s in range(1, 8):
        ones += (v >> s) & 1
    out += [(v & 0xFE) | (1 - ones % 2)]
fixed = from_ints(out)

서식 문자열(f-string)을 활용한 사용자 정의 검증 에러

입력 key: bytes, 출력 ok: bytes. key가 16바이트가 아니면 상세 에러 메시지와 함께 실행을 중단한다.

if len(key) != 16:
    fail("BAD_KEY_LENGTH", f"key must be 16 bytes, got {len(key)} ({key:x})")
ok = key

상세 문서